Updates from master repo. Can now compile both userland and kernel.
authorragge <ragge@openbsd.org>
Sun, 17 Aug 2008 18:40:12 +0000 (18:40 +0000)
committerragge <ragge@openbsd.org>
Sun, 17 Aug 2008 18:40:12 +0000 (18:40 +0000)
(with some patches...)

38 files changed:
usr.bin/pcc/cc/Makefile
usr.bin/pcc/cc/cc.1
usr.bin/pcc/cc/cc.c
usr.bin/pcc/ccconfig.h
usr.bin/pcc/ccom/cgram.y
usr.bin/pcc/ccom/gcc_compat.c
usr.bin/pcc/ccom/init.c
usr.bin/pcc/ccom/main.c
usr.bin/pcc/ccom/optim.c
usr.bin/pcc/ccom/pass1.h
usr.bin/pcc/ccom/pftn.c
usr.bin/pcc/ccom/scan.l
usr.bin/pcc/ccom/stabs.c
usr.bin/pcc/ccom/symtabs.c
usr.bin/pcc/ccom/trees.c
usr.bin/pcc/config.h
usr.bin/pcc/cpp/cpp.1
usr.bin/pcc/cpp/cpp.c
usr.bin/pcc/cpp/cpp.h
usr.bin/pcc/cpp/cpy.y
usr.bin/pcc/cpp/scanner.l
usr.bin/pcc/i386/code.c
usr.bin/pcc/i386/local.c
usr.bin/pcc/i386/local2.c
usr.bin/pcc/i386/macdefs.h
usr.bin/pcc/i386/table.c
usr.bin/pcc/mip/common.c
usr.bin/pcc/mip/manifest.h
usr.bin/pcc/mip/match.c
usr.bin/pcc/mip/mkext.c
usr.bin/pcc/mip/node.h
usr.bin/pcc/mip/optim2.c
usr.bin/pcc/mip/pass2.h
usr.bin/pcc/mip/protos.h
usr.bin/pcc/mip/reader.c
usr.bin/pcc/mip/regs.c
usr.bin/pcc/vax/local.c
usr.bin/pcc/vax/local2.c

index a2e7d4f..1dbca15 100644 (file)
@@ -1,15 +1,18 @@
-#      $OpenBSD: Makefile,v 1.5 2007/10/22 13:40:08 otto Exp $
+#      $OpenBSD: Makefile,v 1.6 2008/08/17 18:40:12 ragge Exp $
 #
 # Makefile for the cc part of pcc.
 #
-PROG=          cc
+PROG=          pcc
+SRCS=          cc.c
+MAN=           cc.1
 PREFIX=                /usr/local
 BINDIR=                ${PREFIX}/bin
 MANDIR=                ${PREFIX}/man/man
 TARGOS=                openbsd
 TARGMACH=       ${MACHINE_ARCH}
+#LINKS=                ${PREFIX}/bin/pcc ${PREFIX}/bin/cc
 
-CFLAGS+=       -DLIBEXECDIR=\"${PREFIX}/libexec\"
+CFLAGS+=       -DLIBEXECDIR=\"${PREFIX}/libexec/\"
 CPPFLAGS+=     -I${.CURDIR}/..
 CPPFLAGS+=     -DDEFMACH=\"${TARGMACH}\"
 
index 75841c1..d37ce5c 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: cc.1,v 1.4 2008/04/11 20:45:52 stefan Exp $
+.\"    $OpenBSD: cc.1,v 1.5 2008/08/17 18:40:12 ragge Exp $
 .\"
 .\" Copyright (c) 2007 Jeremy C. Reed <reed@reedmedia.net>
 .\"
@@ -55,22 +55,29 @@ Unrecognized options are all sent directly to
 Filenames that end with
 .Sy \&.c
 are passed via
-.Xr cpp 1 -\*[Gt]
-.Xr ccom 1 -\*[Gt]
-.Xr as 1 -\*[Gt]
+.Xr cpp 1 -\*(Gt
+.Xr ccom 1 -\*(Gt
+.Xr as 1 -\*(Gt
 .Xr ld 1 .
 .Pp
 Filenames that end with
 .Sy \&.i
 are passed via
-.Xr ccom 1 -\*[Gt]
-.Xr as 1 -\*[Gt]
+.Xr ccom 1 -\*(Gt
+.Xr as 1 -\*(Gt
 .Xr ld 1 .
 .Pp
 Filenames that end with
 .Sy \&.s
 are passed via
-.Xr as 1 -\*[Gt]
+.Xr as 1 -\*(Gt
+.Xr ld 1 .
+.Pp
+Filenames that end with
+.Sy \&.S
+are passed via
+.Xr cpp 1 -\*(Gt
+.Xr as 1 -\*(Gt
 .Xr ld 1 .
 .Pp
 Filenames that end with
@@ -238,6 +245,9 @@ if multiple files are given.
 Do not use dynamic linkage.
 By default, it will link using the dynamic linker options
 and/or shared objects for the platform.
+.It Fl shared
+Create a shared object of the result.  Tells the linker not to 
+generate an executable.
 .It Fl t
 Passes
 .Fl t
@@ -258,7 +268,12 @@ Options for the linker.
 .It Fl X
 Don't remove temporary files on exit.
 .It Fl x
-TODO
+May be used to give separate optimization flags to ccom, see
+.Fl O
+for options.
+.It Fl x Ar c
+Gcc compatibility option; specify that the language in use is
+.Ar c .
 .El
 .Ss Predefined Macros
 A few
index 23cf8be..0bbe81d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cc.c,v 1.13 2008/04/11 20:45:52 stefan Exp $  */
+/*     $OpenBSD: cc.c,v 1.14 2008/08/17 18:40:12 ragge Exp $   */
 /*
  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
  *
 #include <string.h>
 #include <unistd.h>
 
+#ifdef WIN32
+#include <windows.h>
+#include <process.h>
+#include <io.h>
+#endif
+
 #include "../config.h"
 #include "ccconfig.h"
+
+#define MULTITARGET
+
 /* C command */
 
 #define        MKS(x) _MKS(x)
 /*
  * Many specific definitions, should be declared elsewhere.
  */
-#define        STDINC    "/usr/include"
+
+#ifndef STDINC
+#define        STDINC          "/usr/include/"
+#endif
+
+#ifndef LIBDIR
+#define LIBDIR         "/usr/lib/"
+#endif
+
+#ifndef PREPROCESSOR
+#define PREPROCESSOR   "cpp"
+#endif
+
+#ifndef COMPILER
+#define COMPILER       "ccom";
+#endif
+
+#ifndef ASSEMBLER
+#define ASSEMBLER      "as"
+#endif
+
+#ifndef LINKER
+#define LINKER         "ld"
+#endif
+
+#define OS MKS(TARGOS)
+#define MACH MKS(TARGMACH)
+#ifndef PCCINCDIR
+#define PCCINCDIR      LIBDIR "pcc/" MACH "-" OS "/" PACKAGE_VERSION "/include"
+#endif
+#ifndef PCCLIBDIR
+#define PCCLIBDIR      LIBDIR "pcc/" MACH "-" OS "/" PACKAGE_VERSION "/lib"
+#endif
 
 #define MAXFIL 10000
 #define MAXLIB 10000
 char   *tmp3;
 char   *tmp4;
 char   *outfile;
-char *copy(char *),*setsuf(char *, char);
+char *Bprefix(char *);
+char *copy(char *, int),*setsuf(char *, char);
 int getsuf(char *);
 int main(int, char *[]);
 void error(char *, ...);
@@ -89,16 +131,23 @@ int callsys(char [], char *[]);
 int cunlink(char *);
 void dexit(int);
 void idexit(int);
-char *gettmp();
+char *gettmp(void);
+void *ccmalloc(int size);
 char   *av[MAXAV];
 char   *clist[MAXFIL];
 char   *llist[MAXLIB];
+char   *aslist[MAXAV];
 char   alist[20];
 char   *xlist[100];
 int    xnum;
 char   *mlist[100];
+char   *flist[100];
+char   *wlist[100];
 char   *idirafter;
 int    nm;
+int    nf;
+int    nw;
+int    sspflag;
 int    Cflag;
 int    dflag;
 int    pflag;
@@ -117,21 +166,43 @@ int       Mflag;  /* dependencies only */
 int    pgflag;
 int    exfail;
 int    Xflag;
-int    Werror;
-int    nostartfiles, Bstatic;
+int    Wallflag;
+int    Wflag;
+int    nostartfiles, Bstatic, shared;
 int    nostdinc, nostdlib;
 int    onlyas;
 int    pthreads;
+int    xcflag;
+int    ascpp;
 
-char   *pass0;
-char   *passp = LIBEXECDIR "/cpp";
+char   *passp = LIBEXECDIR PREPROCESSOR;
+char   *pass0 = LIBEXECDIR COMPILER;
+char   *as = ASSEMBLER;
+char   *ld = LINKER;
 char   *Bflag;
 char *cppadd[] = CPPADD;
+#ifdef DYNLINKER
 char *dynlinker[] = DYNLINKER;
+#endif
+#ifdef CRT0FILE
 char *crt0file = CRT0FILE;
+#endif
+#ifdef CRT0FILE_PROFILE
 char *crt0file_profile = CRT0FILE_PROFILE;
+#endif
+#ifdef STARTFILES
 char *startfiles[] = STARTFILES;
 char *endfiles[] = ENDFILES;
+#endif
+#ifdef STARTFILES_T
+char *startfiles_T[] = STARTFILES_T;
+char *endfiles_T[] = ENDFILES_T;
+#endif
+#ifdef STARTFILES_S
+char *startfiles_S[] = STARTFILES_S;
+char *endfiles_S[] = ENDFILES_S;
+#endif
+#ifdef MULTITARGET
 char *mach = DEFMACH;
 struct cppmd {
        char *mach;
@@ -139,6 +210,9 @@ struct cppmd {
 };
 
 struct cppmd cppmds[] = CPPMDADDS;
+#else
+char *cppmdadd[] = CPPMDADD;
+#endif
 #ifdef LIBCLIBS
 char *libclibs[] = LIBCLIBS;
 #else
@@ -152,16 +226,45 @@ char *libclibs_profile[] = { "-lc_p", NULL };
 #ifndef STARTLABEL
 #define STARTLABEL "__start"
 #endif
+char *incdir = STDINC;
+char *libdir = PCCLIBDIR;
+
+/* handle gcc warning emulations */
+struct Wflags {
+       char *name;
+       int flags;
+#define        INWALL          1
+#define        NEGATIVE        2
+} Wflags[] = {
+       { "-Werror", 0 },
+       { "-Wshadow", 0 },
+       { "-Wno-shadow", NEGATIVE },
+       { "-Wpointer-sign", INWALL },
+       { "-Wno-pointer-sign", NEGATIVE },
+       { "-Wsign-compare", 0 },
+       { "-Wno-sign-compare", NEGATIVE },
+       { "-Wunknown-pragmas", INWALL },
+       { "-Wno-unknown-pragmas", NEGATIVE },
+       { "-Wunreachable-code", 0 },
+       { "-Wno-unreachable-code", NEGATIVE },
+       { 0, 0 },
+};
+
+#define        SZWFL   (sizeof(Wflags)/sizeof(Wflags[0]))
 
 int
 main(int argc, char *argv[])
 {
+       struct Wflags *Wf;
        char *t, *u;
        char *assource;
        char **pv, *ptemp[MAXOPT], **pvt;
-       int nc, nl, i, j, k, c, nxo, na;
+       int nc, nl, nas, i, j, c, nxo, na;
+#ifdef MULTITARGET
+       int k;
+#endif
 
-       i = nc = nl = nxo = 0;
+       i = nc = nl = nas = nxo = 0;
        pv = ptemp;
        while(++i < argc) {
                if (argv[i][0] == '-') {
@@ -174,10 +277,20 @@ main(int argc, char *argv[])
                                break;
 #endif
 
+                       case '-': /* double -'s */
+                               if (strcmp(argv[i], "--version") == 0)
+                                       printf("%s\n", VERSSTR);
+                               else if (strcmp(argv[i], "--param") == 0)
+                                       /* NOTHING YET */;
+                               else
+                                       error("unrecognized option %s", argv[i]);
+                               break;
+
                        case 'B': /* other search paths for binaries */
                                Bflag = &argv[i][2];
                                break;
-                               
+
+#ifdef MULTITARGET
                        case 'b':
                                t = &argv[i][2];
                                if (*t == '\0' && i + 1 < argc) {
@@ -200,14 +313,13 @@ main(int argc, char *argv[])
                                if (cppmds[j].mach == NULL)
                                        errorx(1, "unknown target arch %s", t);
                                break;
-                               
+#endif
+
                        case 'X':
                                Xflag++;
                                break;
                        case 'W': /* Ignore (most of) W-flags */
-                               if (strncmp(argv[i], "-Werror", 7) == 0) {
-                                       Werror = 1;
-                               } else if (strncmp(argv[i], "-Wl,", 4) == 0) {
+                               if (strncmp(argv[i], "-Wl,", 4) == 0) {
                                        /* options to the linker */
                                        t = &argv[i][4];
                                        while ((u = strchr(t, ','))) {
@@ -216,18 +328,67 @@ main(int argc, char *argv[])
                                                t = u;
                                        }
                                        llist[nl++] = t;
+                               } else if (strncmp(argv[i], "-Wa,", 4) == 0) {
+                                       /* options to the assembler */
+                                       t = &argv[i][4];
+                                       while ((u = strchr(t, ','))) {
+                                               *u++ = 0;
+                                               aslist[nas++] = t;
+                                               t = u;
+                                       }
+                                       aslist[nas++] = t;
                                } else if (strncmp(argv[i], "-Wp,", 4) == 0) {
                                        /* preprocessor */
                                        if (!strncmp(argv[i], "-Wp,-C", 6))
                                                Cflag++;
+                               } else if (strcmp(argv[i], "-Wall") == 0) {
+                                       Wallflag = 1;
+                               } else if (strcmp(argv[i], "-WW") == 0) {
+                                       Wflag = 1;
+                               } else {
+                                       /* check and set if available */
+                                       for (Wf = Wflags; Wf->name; Wf++) {
+                                               if (strcmp(argv[i], Wf->name))
+                                                       continue;
+                                               wlist[nw++] = Wf->name;
+                                       }
                                }
                                break;
 
                        case 'f': /* GCC compatibility flags */
                                if (strcmp(argv[i], "-fPIC") == 0)
                                        kflag = F_PIC;
-                               if (strcmp(argv[i], "-fpic") == 0)
+                               else if (strcmp(argv[i], "-fpic") == 0)
                                        kflag = F_pic;
+                               else if (strcmp(argv[i],
+                                   "-fsigned-char") == 0)
+                                       flist[nf++] = argv[i];
+                               else if (strcmp(argv[i],
+                                   "-fno-signed-char") == 0)
+                                       flist[nf++] = argv[i];
+                               else if (strcmp(argv[i],
+                                   "-funsigned-char") == 0)
+                                       flist[nf++] = argv[i];
+                               else if (strcmp(argv[i],
+                                   "-fno-unsigned-char") == 0)
+                                       flist[nf++] = argv[i];
+                               else if (strcmp(argv[i],
+                                   "-fstack-protector") == 0) {
+                                       flist[nf++] = argv[i];
+                                       sspflag++;
+                               } else if (strcmp(argv[i],
+                                   "-fstack-protector-all") == 0) {
+                                       flist[nf++] = argv[i];
+                                       sspflag++;
+                               } else if (strcmp(argv[i],
+                                   "-fno-stack-protector") == 0) {
+                                       flist[nf++] = argv[i];
+                                       sspflag = 0;
+                               } else if (strcmp(argv[i],
+                                   "-fno-stack-protector-all") == 0) {
+                                       flist[nf++] = argv[i];
+                                       sspflag = 0;
+                               }
                                /* silently ignore the rest */
                                break;
 
@@ -269,7 +430,8 @@ main(int argc, char *argv[])
                                break;
 
                        case 'p':
-                               if (strcmp(argv[i], "-pg") == 0)
+                               if (strcmp(argv[i], "-pg") == 0 ||
+                                   strcmp(argv[i], "-p") == 0)
                                        pgflag++;
                                else if (strcmp(argv[i], "-pthread") == 0)
                                        pthreads++;
@@ -284,10 +446,12 @@ main(int argc, char *argv[])
                                if (*t == 0)
                                        t = argv[++i];
                                if (strcmp(t, "c") == 0)
-                                       ; /* default */
+                                       xcflag = 1; /* default */
+                               else if (strcmp(t, "assembler-with-cpp") == 0)
+                                       ascpp = 1;
 #ifdef notyet
-                               else if (strcmp(t, "c++"))
-                                       cxxflag;
+                               else if (strcmp(t, "c++") == 0)
+                                       cxxflag++;
 #endif
                                else
                                        xlist[xnum++] = argv[i];
@@ -305,7 +469,10 @@ main(int argc, char *argv[])
                                outfile = argv[++i];
                                break;
                        case 'O':
-                               Oflag++;
+                               if (argv[i][2] == '0')
+                                       Oflag = 0;
+                               else
+                                       Oflag++;
                                break;
                        case 'E':
                                Eflag++;
@@ -357,7 +524,14 @@ main(int argc, char *argv[])
                        case 's':
                                if (strcmp(argv[i], "-static") == 0)
                                        Bstatic = 1;
-                               else
+                               else if (strcmp(argv[i], "-shared") == 0) {
+                                       shared = 1;
+#ifndef os_win32
+                                       nostdlib = 1;
+#endif
+                               } else if (strncmp(argv[i], "-std", 4) == 0) {
+                                       /* ignore gcc -std= */;
+                               } else
                                        goto passa;
                                break;
                        }
@@ -367,7 +541,7 @@ main(int argc, char *argv[])
                        if (*argv[i] == '-' && argv[i][1] == 'L')
                                ;
                        else if((c=getsuf(t))=='c' || c=='S' || c=='i' ||
-                           c=='s'|| Eflag) {
+                           c=='s'|| Eflag || xcflag) {
                                clist[nc++] = t;
                                if (nc>=MAXFIL) {
                                        error("Too many source files");
@@ -411,11 +585,17 @@ main(int argc, char *argv[])
                        tmp3 = gettmp();
                tmp4 = gettmp();
        }
+       if (Bflag) {
+               incdir = Bflag;
+               libdir = Bflag;
+       }
        if (signal(SIGINT, SIG_IGN) != SIG_IGN) /* interrupt */
                signal(SIGINT, idexit);
        if (signal(SIGTERM, SIG_IGN) != SIG_IGN)        /* terminate */
                signal(SIGTERM, idexit);
+#ifdef MULTITARGET
        asprintf(&pass0, "%s%s%s", LIBEXECDIR, "/ccom_", mach);
+#endif
        pvt = pv;
        for (i=0; i<nc; i++) {
                /*
@@ -425,15 +605,18 @@ main(int argc, char *argv[])
                        printf("%s:\n", clist[i]);
                onlyas = 0;
                assource = tmp3;
+               if (getsuf(clist[i])=='S')
+                       ascpp = 1;
                if (getsuf(clist[i])=='i') {
                        if(Eflag)
                                continue;
                        goto com;
+               } else if (ascpp) {
+                       onlyas = 1;
                } else if (getsuf(clist[i])=='s') {
                        assource = clist[i];
                        goto assemble;
-               } else if (getsuf(clist[i])=='S')
-                       onlyas = 1;
+               }
                if (pflag)
                        tmp4 = setsuf(clist[i], 'i');
                na = 0;
@@ -443,8 +626,10 @@ main(int argc, char *argv[])
                av[na++] = "-D__PCC__=" MKS(PCC_MAJOR);
                av[na++] = "-D__PCC_MINOR__=" MKS(PCC_MINOR);
                av[na++] = "-D__PCC_MINORMINOR__=" MKS(PCC_MINORMINOR);
-               if (getsuf(clist[i])=='S')
+               if (ascpp)
                        av[na++] = "-D__ASSEMBLER__";
+               if (sspflag)
+                       av[na++] = "-D__SSP__=1";
                if (pthreads)
                        av[na++] = "-D_PTHREADS";
                if (Cflag)
@@ -455,6 +640,7 @@ main(int argc, char *argv[])
                        av[na++] = alist;
                for (j = 0; cppadd[j]; j++)
                        av[na++] = cppadd[j];
+#ifdef MULTITARGET
                for (k = 0; cppmds[k].mach; k++) {
                        if (strcmp(cppmds[k].mach, mach) != 0)
                                continue;
@@ -462,12 +648,17 @@ main(int argc, char *argv[])
                                av[na++] = cppmds[k].cppmdadd[j];
                        break;
                }
+#else
+               for (j = 0; cppmdadd[j]; j++)
+                       av[na++] = cppmdadd[j];
+#endif
                if (tflag)
                        av[na++] = "-t";
                for(pv=ptemp; pv <pvt; pv++)
                        av[na++] = *pv;
                if (!nostdinc)
-                       av[na++] = "-S", av[na++] = STDINC;
+                       av[na++] = "-S", av[na++] = incdir;
+               av[na++] = "-I", av[na++] = PCCINCDIR;
                if (idirafter) {
                        av[na++] = "-I";
                        av[na++] = idirafter;
@@ -493,16 +684,40 @@ main(int argc, char *argv[])
        com:
                na = 0;
                av[na++]= "ccom";
+               if (Wallflag) {
+                       /* Set only the same flags as gcc */
+                       for (Wf = Wflags; Wf->name; Wf++) {
+                               if (Wf->flags != INWALL)
+                                       continue;
+                               av[na++] = Wf->name;
+                       }
+               }
+               if (Wflag) {
+                       /* set all positive flags */
+                       for (Wf = Wflags; Wf->name; Wf++) {
+                               if (Wf->flags == NEGATIVE)
+                                       continue;
+                               av[na++] = Wf->name;
+                       }
+               }
+               for (j = 0; j < nw; j++)
+                       av[na++] = wlist[j];
+               for (j = 0; j < nf; j++)
+                       av[na++] = flist[j];
                if (vflag)
                        av[na++] = "-v";
                if (pgflag)
                        av[na++] = "-p";
                if (gflag)
                        av[na++] = "-g";
+#ifdef os_darwin
+               /* darwin always wants PIC compilation */
+               if (!Bstatic)
+                       av[na++] = "-k";
+#else
                if (kflag)
                        av[na++] = "-k";
-               if (Werror)
-                       av[na++] = "-Werror";
+#endif
                if (Oflag) {
                        av[na++] = "-xtemps";
                        av[na++] = "-xdeljumps";
@@ -548,7 +763,16 @@ main(int argc, char *argv[])
                 */
        assemble:
                na = 0;
-               av[na++] = "as";
+               av[na++] = as;
+               for (j = 0; j < nas; j++)
+                       av[na++] = aslist[j];
+#if defined(os_sunos) && defined(mach_sparc64)
+               av[na++] = "-m64";
+#endif
+#if defined(os_darwin)
+               if (Bstatic)
+                       av[na++] = "-static";
+#endif
                if (vflag)
                        av[na++] = "-v";
                if (kflag)
@@ -562,7 +786,7 @@ main(int argc, char *argv[])
                if (dflag)
                        av[na++] = alist;
                av[na++] = 0;
-               if (callsys("/bin/as", av)) {
+               if (callsys(as, av)) {
                        cflag++;
                        eflag++;
                        cunlink(tmp4);
@@ -580,27 +804,85 @@ main(int argc, char *argv[])
 nocom:
        if (cflag==0 && nl!=0) {
                j = 0;
-               av[j++] = "ld";
+               av[j++] = ld;
+#ifndef MSLINKER
                if (vflag)
                        av[j++] = "-v";
+#endif
+#if !defined(os_sunos) && !defined(os_win32)
                av[j++] = "-X";
-               av[j++] = "-d";
-               av[j++] = "-e";
-               av[j++] = STARTLABEL;
-               if (Bstatic == 0) { /* Dynamic linkage */
-                       for (i = 0; dynlinker[i]; i++)
-                               av[j++] = dynlinker[i];
-               } else
-                       av[j++] = "-Bstatic";
+#endif
+               if (shared) {
+                       av[j++] = "-shared";
+#ifdef os_win32
+                       av[j++] = "-Bdynamic";
+#endif
+#ifndef os_sunos
+               } else {
+#ifndef os_win32
+#ifndef os_darwin
+                       av[j++] = "-d";
+#endif
+                       av[j++] = "-e";
+                       av[j++] = STARTLABEL;
+#endif
+#endif
+                       if (Bstatic == 0) { /* Dynamic linkage */
+#ifdef DYNLINKER
+                               for (i = 0; dynlinker[i]; i++)
+                                       av[j++] = dynlinker[i];
+#endif
+                       } else {
+#ifdef os_darwin
+                               av[j++] = "-static";
+#else
+                               av[j++] = "-Bstatic";
+#endif
+                       }
+               }
                if (outfile) {
+#ifdef MSLINKER
+                       char *s = copy("/OUT:", strlen(outfile));
+                       strcat(s, outfile);
+                       av[j++] = s;
+#else
                        av[j++] = "-o";
                        av[j++] = outfile;
+#endif
                }
-               if (!nostartfiles) {
-                       av[j++] = crt0file;
-                       av[j++] = pgflag ? crt0file_profile : crt0file;
-                       for (i = 0; startfiles[i]; i++)
-                               av[j++] = startfiles[i];
+#ifdef STARTFILES_S
+               if (shared) {
+                       if (!nostartfiles) {
+                               for (i = 0; startfiles_S[i]; i++)
+                                       av[j++] = Bprefix(startfiles_S[i]);
+                       }
+               } else
+#endif
+               {
+                       if (!nostartfiles) {
+#ifdef CRT0FILE_PROFILE
+                               if (pgflag) {
+                                       av[j++] = Bprefix(crt0file_profile);
+                               } else
+#endif
+                               {
+#ifdef CRT0FILE
+                                       av[j++] = Bprefix(crt0file);
+#endif
+                               }
+#ifdef STARTFILES_T
+                               if (Bstatic) {
+                                       for (i = 0; startfiles_T[i]; i++)
+                                               av[j++] = Bprefix(listartfiles_T[i]);
+                               } else
+#endif
+                               {
+#ifdef STARTFILES
+                                       for (i = 0; startfiles[i]; i++)
+                                               av[j++] = Bprefix(startfiles[i]);
+#endif
+                               }
+                       }
                }
                i = 0;
                while(i<nl) {
@@ -608,8 +890,11 @@ nocom:
                        if (j >= MAXAV)
                                error("Too many ld options");
                }
+#ifndef MACHOABI
+               /* darwin assembler doesn't want -g */
                if (gflag)
                        av[j++] = "-g";
+#endif
 #if 0
                if (gflag)
                        av[j++] = "-lg";
@@ -617,22 +902,45 @@ nocom:
                if (pthreads)
                        av[j++] = "-lpthread";
                if (!nostdlib) {
+#ifdef MSLINKER
+                       char *s = copy("/LIBPATH:", strlen(libdir));
+#else
+                       char *s = copy("-L", strlen(libdir));
+#endif
+                       strcat(s, libdir);
+                       av[j++] = s;
                        if (pgflag) {
                                for (i = 0; libclibs_profile[i]; i++)
-                                       av[j++] = libclibs_profile[i];
+                                       av[j++] = Bprefix(libclibs_profile[i]);
                        } else {
                                for (i = 0; libclibs[i]; i++)
-                                       av[j++] = libclibs[i];
+                                       av[j++] = Bprefix(libclibs[i]);
                        }
-                       for (i = 0; libclibs[i]; i++)
-                               av[j++] = libclibs[i];
                }
                if (!nostartfiles) {
-                       for (i = 0; endfiles[i]; i++)
-                               av[j++] = endfiles[i];
+#ifdef STARTFILES_S
+                       if (shared) {
+                               for (i = 0; endfiles_S[i]; i++)
+                                       av[j++] = Bprefix(endfiles_S[i]);
+                       } else 
+#endif
+                       {
+#ifdef STARTFILES_T
+                               if (Bstatic) {
+                                       for (i = 0; endfiles_T[i]; i++)
+                                               av[j++] = Bprefix(endfiles_T[i]);
+                               } else
+#endif
+                               {
+#ifdef STARTFILES
+                                       for (i = 0; endfiles[i]; i++)
+                                               av[j++] = Bprefix(endfiles[i]);
+#endif
+                               }
+                       }
                }
                av[j++] = 0;
-               eflag |= callsys("/bin/ld", av);
+               eflag |= callsys(ld, av);
                if (nc==1 && nxo==1 && eflag==0)
                        cunlink(setsuf(clist[0], 'o'));
                else if (nc > 0 && eflag == 0) {
@@ -707,13 +1015,31 @@ errorx(int eval, char *s, ...)
        dexit(eval);
 }
 
+char *
+Bprefix(char *s)
+{
+       char *suffix;
+       char *str;
+
+       if (Bflag == NULL || s[0] != '/')
+               return s;
+
+       suffix = strrchr(s, '/');
+       if (suffix == NULL)
+               suffix = s;
+
+       str = copy(Bflag, strlen(suffix));
+       strcat(str, suffix);
+       return str;
+}
+
 int
-getsuf(char *as)
+getsuf(char *s)
 {
-       register char *s;
+       register char *p;
 
-       if ((s = strrchr(as, '.')) && s[1] != '\0' && s[2] == '\0')
-               return s[1];
+       if ((p = strrchr(s, '.')) && p[1] != '\0' && p[2] == '\0')
+               return p[1];
        return(0);
 }
 
@@ -723,13 +1049,69 @@ getsuf(char *as)
 char *
 setsuf(char *s, char ch)
 {
-       s = copy(basename(s));
-       s[strlen(s) - 1] = ch;
+       char *p;
+
+       s = copy(basename(s), 2);
+       if ((p = strrchr(s, '.')) == NULL) {
+               p = s + strlen(s);
+               p[0] = '.';
+       }
+       p[1] = ch;
+       p[2] = '\0';
        return(s);
 }
 
+#ifdef WIN32
+int
+callsys(char *f, char *v[])
+{
+       char *s;
+       int t, status = 0;
+       char cmd[MAX_PATH];
+       int len;
+       STARTUPINFO si;
+       PROCESS_INFORMATION pi;
+       DWORD exitCode;
+       BOOL ok;
+
+       len = strlcpy(cmd, f, MAX_PATH);
+       for (t = 1; v[t] && len < MAX_PATH; t++) {
+               len = strlcat(cmd, " ", MAX_PATH);
+               len = strlcat(cmd, v[t], MAX_PATH);
+       }
+
+       if (vflag)
+               printf("%s\n", cmd);
+
+       ZeroMemory(&si, sizeof(STARTUPINFO));
+       si.cb = sizeof(STARTUPINFO);
+       ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+
+       ok = CreateProcess(NULL,  // the executable program
+               cmd,   // the command line arguments
+               NULL,       // ignored
+               NULL,       // ignored
+               TRUE,       // inherit handles
+               HIGH_PRIORITY_CLASS,
+               NULL,       // ignored
+               NULL,       // ignored
+               &si,
+               &pi);
+
+       if (!ok) {
+               printf("Try Again\n");
+               return 100;
+       }
+
+       WaitForSingleObject(pi.hProcess, INFINITE);
+       GetExitCodeProcess(pi.hProcess, &exitCode);
+       return (exitCode != 0);
+}
+
+#else
+
 int
-callsys(char f[], char *v[])
+callsys(char *f, char *v[])
 {
        int t, status = 0;
        pid_t p;
@@ -756,7 +1138,7 @@ callsys(char f[], char *v[])
                                execv(a, v);
                        }
                }
-               execv(f, v);
+               execvp(f, v);
                if ((s = strrchr(f, '/')))
                        execvp(s+1, v);
                fprintf(stderr, "Can't find %s\n", f);
@@ -772,19 +1154,25 @@ callsys(char f[], char *v[])
        if (WIFEXITED(status))
                return (WEXITSTATUS(status));
        if (WIFSIGNALED(status))
-               dexit(eflag);
+               dexit(eflag ? eflag : 1);
        errorx(8, "Fatal error in %s", f);
+
+       return 0;
 }
+#endif
 
+/*
+ * Make a copy of string as, mallocing extra bytes in the string.
+ */
 char *
-copy(char *as)
+copy(char *s, int extra)
 {
-       char *p;
-
-       if ((p = strdup(as)) == NULL)
-               errorx(8, "no space for file names");
+       int len = strlen(s)+1;
+       char *rv;
 
-       return p;
+       rv = ccmalloc(len+extra);
+       strlcpy(rv, s, len);
+       return rv;
 }
 
 int
@@ -792,13 +1180,38 @@ cunlink(char *f)
 {
        if (f==0 || Xflag)
                return(0);
-       return(unlink(f));
+       return (unlink(f));
 }
 
+#ifdef WIN32
 char *
 gettmp(void)
 {
-       char *sfn = copy("/tmp/ctm.XXXXXX");
+#define BUFFSIZE 1000
+       DWORD pathSize;
+       char pathBuffer[BUFFSIZE];
+       char tempFilename[MAX_PATH];
+       UINT uniqueNum;
+
+       pathSize = GetTempPath(BUFFSIZE, pathBuffer);
+       if (pathSize < BUFFSIZE)
+               pathBuffer[pathSize] = 0;
+       else
+               pathBuffer[0] = 0;
+       uniqueNum = GetTempFileName(pathBuffer, "ctm", 0, tempFilename);
+       if (uniqueNum == 0) {
+               fprintf(stderr, "%s:\n", pathBuffer);
+               exit(8);
+       }
+       return copy(tempFilename, 0);
+}
+
+#else
+
+char *
+gettmp(void)
+{
+       char *sfn = copy("/tmp/ctm.XXXXXX", 0);
        int fd = -1;
 
        if ((fd = mkstemp(sfn)) == -1) {
@@ -806,6 +1219,16 @@ gettmp(void)
                exit(8);
        }
        close(fd);
-
        return sfn;
 }
+#endif
+
+void *
+ccmalloc(int size)
+{
+       void *rv;
+
+       if ((rv = malloc(size)) == NULL)
+               error("malloc failed");
+       return rv;
+}
index c7fe056..45cda23 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ccconfig.h,v 1.4 2008/04/11 20:45:51 stefan Exp $     */
+/*     $OpenBSD: ccconfig.h,v 1.5 2008/08/17 18:40:12 ragge Exp $      */
 
 /*
  * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
@@ -64,4 +64,5 @@
 }
 #define MAXCPPMDARGS 8
 
+#define ELFABI
 #define        STABS
index 2af2844..9d9d03b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cgram.y,v 1.9 2008/04/11 20:45:52 stefan Exp $        */
+/*     $OpenBSD: cgram.y,v 1.10 2008/08/17 18:40:12 ragge Exp $        */
 
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
@@ -79,7 +79,6 @@
 /*
  * Token used in C lex/yacc communications.
  */
-%token C_WSTRING       /* a wide string constant */
 %token C_STRING        /* a string constant */
 %token C_ICON          /* an integer constant */
 %token C_FCON          /* a floating point constant */
 # include <string.h>
 # include <stdlib.h>
 
-static int fun_inline; /* Reading an inline function */
+int fun_inline;        /* Reading an inline function */
 int oldstyle;  /* Current function being defined */
-int noretype;
 static struct symtab *xnf;
 extern int enummer, tvaloff;
 extern struct rstack *rpole;
-static int ctval;
+static int ctval, widestr;
+
+#define        NORETYP SNOCREAT /* no return type, save in unused field in symtab */
 
 static NODE *bdty(int op, ...);
 static void fend(void);
@@ -170,7 +170,10 @@ static NODE *cmop(NODE *l, NODE *r);
 static NODE *xcmop(NODE *out, NODE *in, NODE *str);
 static void mkxasm(char *str, NODE *p);
 static NODE *xasmop(char *str, NODE *p);
-
+static int maxstlen(char *str);
+static char *stradd(char *old, char *new);
+static NODE *biop(int op, NODE *l, NODE *r);
+static void flend(void);
 
 /*
  * State for saving current switch state (when nested switches).
@@ -204,9 +207,9 @@ struct savbc {
                parameter_type_list parameter_list addrlbl
                declaration_specifiers pointer direct_abstract_declarator
                specifier_qualifier_list merge_specifiers nocon_e
-               identifier_list arg_param_list arg_declaration arg_dcl_list
-               designator_list designator xasm oplist oper cnstr
-%type <strp>   string wstring C_STRING C_WSTRING
+               identifier_list arg_param_list
+               designator_list designator xasm oplist oper cnstr funtype
+%type <strp>   string C_STRING
 %type <rp>     str_head
 %type <symp>   xnfdeclarator clbrace enum_head
 
@@ -222,36 +225,22 @@ ext_def_list:        ext_def_list external_def
                | { ftnend(); }
                ;
 
-external_def:     function_definition { blevel = 0; }
+external_def:     funtype kr_args compoundstmt { fend(); }
                |  declaration  { blevel = 0; symclear(0); }
                |  asmstatement ';'
                |  ';'
                |  error { blevel = 0; }
                ;
 
-function_definition:
-       /* Ansi (or K&R header without parameter types) */
-                  declaration_specifiers declarator {
-                       fundef($1, $2);
-               } compoundstmt { fend(); }
-       /* Same as above but without declaring function type */
-               |  declarator {
-                       noretype = 1;
-                       fundef(mkty(INT, 0, MKSUE(INT)), $1);
-               } compoundstmt { fend(); noretype = 0; }
-       /* K&R function without type declaration */
-               |  declarator {
-                       noretype = 1;
-                       if (oldstyle == 0)
-                               uerror("bad declaration in ansi function");
-                       fundef(mkty(INT, 0, MKSUE(INT)), $1);
-               } arg_dcl_list compoundstmt { fend(); noretype = 0; }
-       /* K&R function with type declaration */
-               |  declaration_specifiers declarator {
-                       if (oldstyle == 0)
-                               uerror("bad declaration in ansi function");
-                       fundef($1, $2);
-               } arg_dcl_list compoundstmt { fend(); }
+funtype:         /* no type given */ declarator {
+                   fundef(mkty(INT, 0, MKSUE(INT)), $1);
+                   cftnsp->sflags |= NORETYP;
+               }
+               | declaration_specifiers declarator { fundef($1,$2); }
+               ;
+
+kr_args:         /* empty */
+               | arg_dcl_list
                ;
 
 /*
@@ -274,11 +263,7 @@ merge_attribs:        C_CLASS { $$ = block(CLASS, NIL, NIL, $1, 0, 0); }
                ;
 
 function_specifiers:
-                  C_FUNSPEC {
-                       if (fun_inline)
-                               uerror("too many inline");
-                       fun_inline = 1;
-               }
+                  C_FUNSPEC { fun_inline = 1; }
                ;
 
 type_specifier:           C_TYPE { $$ = $1; }
@@ -336,26 +321,36 @@ direct_declarator: C_NAME { $$ = bdty(NAME, $1); }
                |  '(' declarator ')' { $$ = $2; }
                |  direct_declarator '[' nocon_e ']' { 
                        $3 = optim($3);
-                       if (blevel == 0 && !nncon($3))
+                       if ((blevel == 0 || rpole != NULL) && !nncon($3))
                                uerror("array size not constant");
+                       /*
+                        * Checks according to 6.7.5.2 clause 1:
+                        * "...the expression shall have an integer type."
+                        * "If the expression is a constant expression,
+                        * it shall have a value greater than zero."
+                        */
                        if (!ISINTEGER($3->n_type))
                                werror("array size is not an integer");
-                       else if ($3->n_op == ICON && $3->n_lval < 0) {
-                               uerror("array size must be non-negative");
-                               $3->n_lval = 1;
+                       else if ($3->n_op == ICON) {
+                               if ($3->n_lval < 0) {
+                                       uerror("array size cannot be negative");
+                                       $3->n_lval = 1;
+                               }
+#ifdef notyet
+                               if ($3->n_lval == 0 && Wgcc)
+                                       werror("gcc extension; zero size");
+#endif
                        }
-                       $$ = block(LB, $1, $3, INT, 0, MKSUE(INT));
-               }
-               |  direct_declarator '[' ']' { $$ = bdty(LB, $1, 0); }
-               |  direct_declarator '(' fundcl parameter_type_list ')' {
-                       if (blevel-- > 1)
-                               symclear(blevel);
-                       $$ = bdty(CALL, $1, $4);
-               }
-               |  direct_declarator '(' fundcl identifier_list ')' { 
-                       if (blevel-- > 1)
-                               symclear(blevel);
-                       $$ = bdty(CALL, $1, $4);
+                       $$ = biop(LB, $1, $3);
+               }
+               |  direct_declarator '[' ']' {
+                       $$ = biop(LB, $1, bcon(NOOFFSET));
+               }
+               |  direct_declarator '(' parameter_type_list ')' {
+                       $$ = bdty(CALL, $1, $3);
+               }
+               |  direct_declarator '(' identifier_list ')' { 
+                       $$ = bdty(CALL, $1, $3);
                        if (blevel != 0)
                                uerror("function declaration in bad context");
                        oldstyle = 1;
@@ -366,20 +361,8 @@ direct_declarator: C_NAME { $$ = bdty(NAME, $1); }
                }
                ;
 
-fundcl:                   { if (++blevel == 1) argoff = ARGINIT; ctval = tvaloff; }
-               ;
-
-identifier_list:   C_NAME {
-                       $$ = mkty(FARG, NULL, MKSUE(INT));
-                       $$->n_sp = lookup($1, 0);
-                       defid($$, PARAM);
-               }
-               |  identifier_list ',' C_NAME { 
-                       $$ = mkty(FARG, NULL, MKSUE(INT));
-                       $$->n_sp = lookup($3, 0);
-                       defid($$, PARAM);
-                       $$ = block(CM, $1, $$, 0, 0, 0);
-               }
+identifier_list:   C_NAME { $$ = bdty(NAME, $1); }
+               |  identifier_list ',' C_NAME { $$ = cmop($1, bdty(NAME, $3)); }
                ;
 
 /*
@@ -388,8 +371,7 @@ identifier_list:   C_NAME {
 parameter_type_list:
                   parameter_list { $$ = $1; }
                |  parameter_list ',' C_ELLIPSIS {
-                       $$ = block(CM, $1, block(ELLIPSIS, NIL, NIL, 0, 0, 0),
-                           0, 0, 0);
+                       $$ = cmop($1, biop(ELLIPSIS, NIL, NIL));
                }
                ;
 
@@ -400,7 +382,7 @@ parameter_type_list:
  */
 parameter_list:           parameter_declaration { $$ = $1; }
                |  parameter_list ',' parameter_declaration {
-                       $$ = block(CM, $1, $3, 0, 0, 0);
+                       $$ = cmop($1, $3);
                }
                ;
 
@@ -409,16 +391,9 @@ parameter_list:       parameter_declaration { $$ = $1; }
  */
 parameter_declaration:
                   declaration_specifiers declarator {
-                       if ($1->n_lval == AUTO || $1->n_lval == TYPEDEF ||
-                           $1->n_lval == EXTERN || $1->n_lval == STATIC)
+                       if ($1->n_lval != SNULL && $1->n_lval != REGISTER)
                                uerror("illegal parameter class");
                        $$ = tymerge($1, $2);
-                       if (blevel == 1) {
-                               $$->n_sp = lookup((char *)$$->n_sp, 0);/* XXX */
-                               if (ISFTN($$->n_type))
-                                       $$->n_type = INCREF($$->n_type);
-                               defid($$, PARAM);
-                       }
                        nfree($1);
                
                }
@@ -442,9 +417,11 @@ abstract_declarator:
 
 direct_abstract_declarator:
                   '(' abstract_declarator ')' { $$ = $2; }
-               |  '[' ']' { $$ = bdty(LB, bdty(NAME, NULL), 0); }
+               |  '[' ']' { $$ = biop(LB, bdty(NAME, NULL), bcon(NOOFFSET)); }
                |  '[' con_e ']' { $$ = bdty(LB, bdty(NAME, NULL), $2); }
-               |  direct_abstract_declarator '[' ']' { $$ = bdty(LB, $1, 0); }
+               |  direct_abstract_declarator '[' ']' {
+                       $$ = biop(LB, $1, bcon(NOOFFSET));
+               }
                |  direct_abstract_declarator '[' con_e ']' {
                        $$ = bdty(LB, $1, $3);
                }
@@ -497,10 +474,9 @@ block_item:           declaration
 /*
  * Variables are declared in init_declarator.
  */
-declaration:      declaration_specifiers ';' { nfree($1); goto inl; }
+declaration:      declaration_specifiers ';' { nfree($1); fun_inline = 0; }
                |  declaration_specifiers init_declarator_list ';' {
                        nfree($1);
-                       inl:
                        fun_inline = 0;
                }
                ;
@@ -580,8 +556,7 @@ struct_declarator_list:
 
 struct_declarator: declarator {
                        tymerge($<nodep>0, $1);
-                       soumemb($1, (char *)$1->n_sp,
-                           $<nodep>0->n_lval); /* XXX */
+                       soumemb($1, (char *)$1->n_sp, 0);
                        nfree($1);
                }
                |  ':' con_e {
@@ -652,7 +627,7 @@ designator:    '[' con_e ']' {
                                uerror("designator must be non-negative");
                                $2 = 0;
                        }
-                       $$ = bdty(LB, NULL, $2);
+                       $$ = biop(LB, NIL, bcon($2));
                }
                |  C_STROP C_NAME {
                        if ($1 != DOT)
@@ -670,34 +645,8 @@ ibrace:               '{' {  ilbrace(); }
 
 /*     STATEMENTS      */
 
-compoundstmt:     begin block_item_list '}' {  
-#ifdef STABS
-                       if (gflag && blevel > 2)
-                               stabs_rbrac(blevel);
-#endif
-                       --blevel;
-                       if( blevel == 1 )
-                               blevel = 0;
-                       symclear(blevel); /* Clean ut the symbol table */
-                       if (autooff > maxautooff)
-                               maxautooff = autooff;
-                       autooff = savctx->contlab;
-                       savctx = savctx->next;
-               }
-               |  begin '}' {
-#ifdef STABS
-                       if (gflag && blevel > 2)
-                               stabs_rbrac(blevel);
-#endif
-                       --blevel;
-                       if( blevel == 1 )
-                               blevel = 0;
-                       symclear(blevel); /* Clean ut the symbol table */
-                       if (autooff > maxautooff)
-                               maxautooff = autooff;
-                       autooff = savctx->contlab;
-                       savctx = savctx->next;
-               }
+compoundstmt:     begin block_item_list '}' { flend(); }
+               |  begin '}' { flend(); }
                ;
 
 begin:           '{' {
@@ -719,6 +668,8 @@ begin:                '{' {
                        bc->next = savctx;
                        savctx = bc;
                        bccode();
+                       if (sspflag && blevel == 2)
+                               sspstart();
                }
                ;
 
@@ -788,19 +739,19 @@ statement:           e ';' { ecomp( $1 ); symclear(blevel); }
                }
                |  C_RETURN  ';' {
                        branch(retlab);
-                       if (cftnsp->stype != VOID && noretype &&
+                       if (cftnsp->stype != VOID && 
+                           (cftnsp->sflags & NORETYP) == 0 &&
                            cftnsp->stype != VOID+FTN)
                                uerror("return value required");
                        rch:
-                       if (!reached)
+                       if (!reached && Wunreachable_code)
                                werror( "statement is not reached");
                        reached = 0;
                }
                |  C_RETURN e  ';' {
                        register NODE *temp;
 
-                       spname = cftnsp;
-                       temp = buildtree( NAME, NIL, NIL );
+                       temp = nametree(cftnsp);
                        temp->n_type = DECREF(temp->n_type);
                        temp = buildtree(RETURN, temp, $2);
 
@@ -814,9 +765,7 @@ statement:     e ';' { ecomp( $1 ); symclear(blevel); }
                        reached = 0;
                }
                |  C_GOTO C_NAME ';' { gotolabel($2); goto rch; }
-               |  C_GOTO '*' e ';' {
-                       ecomp(block(GOTO, $3, NIL, INT, 0, 0));
-               }
+               |  C_GOTO '*' e ';' { ecomp(biop(GOTO, $3, NIL)); }
                |  asmstatement ';'
                |   ';'
                |  error  ';'
@@ -824,8 +773,12 @@ statement:    e ';' { ecomp( $1 ); symclear(blevel); }
                |  label statement
                ;
 
-asmstatement:     C_ASM '(' string ')' { send_passt(IP_ASM, mkpstr($3)); }
-               |  C_ASM '(' string xasm ')' { mkxasm($3, $4); }
+asmstatement:     C_ASM mvol '(' string ')' { send_passt(IP_ASM, mkpstr($4)); }
+               |  C_ASM mvol '(' string xasm ')' { mkxasm($4, $5); }
+               ;
+
+mvol:             /* empty */
+               |  C_QUALIFIER { nfree($1); }
                ;
 
 xasm:             ':' oplist { $$ = xcmop($2, NIL, NIL); }
@@ -846,14 +799,13 @@ cnstr:               string { $$ = xasmop($1, bcon(0)); }
                 ;
 
 label:            C_NAME ':' { deflabel($1); reached = 1; }
+               |  C_TYPENAME ':' { deflabel($1); reached = 1; }
                |  C_CASE e ':' { addcase($2); reached = 1; }
                |  C_DEFAULT ':' { reached = 1; adddef(); flostat |= FDEF; }
                ;
 
 doprefix:      C_DO {
                        savebc();
-                       if (!reached)
-                               werror("loop not entered at top");
                        brklab = getlab();
                        contlab = getlab();
                        plabel(  $$ = getlab());
@@ -877,8 +829,6 @@ ifelprefix:   ifprefix statement C_ELSE {
 
 whprefix:        C_WHILE  '('  e  ')' {
                        savebc();
-                       if (!reached)
-                               werror("loop not entered at top");
                        if ($3->n_op == ICON && $3->n_lval != 0)
                                flostat = FLOOP;
                        plabel( contlab = getlab());
@@ -893,8 +843,6 @@ whprefix:     C_WHILE  '('  e  ')' {
 forprefix:       C_FOR  '('  .e  ';' .e  ';' {
                        if ($3)
                                ecomp($3);
-                       else if (!reached)
-                               werror("loop not entered at top");
                        savebc();
                        contlab = getlab();
                        brklab = getlab();
@@ -993,6 +941,7 @@ e:             e ',' e { $$ = buildtree(COMOP, $1, $3); }
                |  e C_DIVOP e { $$ = buildtree($2, $1, $3); }
                |  e '*' e { $$ = buildtree(MUL, $1, $3); }
                |  e '=' addrlbl { $$ = buildtree(ASSIGN, $1, $3); }
+               |  '(' begin block_item_list e ';' '}' ')' { $$ = $4; flend(); }
                |  term
                ;
 
@@ -1001,8 +950,7 @@ addrlbl:     C_ANDAND C_NAME {
                        struct symtab *s = lookup($2, SLBLNAME);
                        if (s->soffset == 0)
                                s->soffset = -getlab();
-                       spname = s;
-                       $$ = buildtree(ADDROF, buildtree(NAME, NIL, NIL), NIL);
+                       $$ = buildtree(ADDROF, nametree(s), NIL);
 #else
                        uerror("gcc extension");
 #endif
@@ -1012,7 +960,7 @@ addrlbl:     C_ANDAND C_NAME {
 term:             term C_INCOP {  $$ = buildtree( $2, $1, bcon(1) ); }
                |  '*' term { $$ = buildtree(UMUL, $2, NIL); }
                |  '&' term {
-                       if( ISFTN($2->n_type) || ISARY($2->n_type) ){
+                       if( ISFTN($2->n_type)/* || ISARY($2->n_type) */){
 #ifdef notdef
                                werror( "& before array or function: ignored" );
 #endif
@@ -1041,8 +989,7 @@ term:                 term C_INCOP {  $$ = buildtree( $2, $1, bcon(1) ); }
                }
                | '(' cast_type ')' clbrace init_list optcomma '}' {
                        endinit();
-                       spname = $4;
-                       $$ = buildtree(NAME, NIL, NIL);
+                       $$ = nametree($4);
                }
                |  term '[' e ']' {
                        $$ = buildtree( UMUL,
@@ -1053,47 +1000,26 @@ term:              term C_INCOP {  $$ = buildtree( $2, $1, bcon(1) ); }
                |  term C_STROP C_NAME { $$ = structref($1, $2, $3); }
                |  term C_STROP C_TYPENAME { $$ = structref($1, $2, $3); }
                |  C_NAME {
-                       spname = lookup($1, 0);
-                       if (spname->sflags & SINLINE)
-                               inline_ref(spname);
-                       $$ = buildtree(NAME, NIL, NIL);
-                       if (spname->sflags & SDYNARRAY)
+                       struct symtab *sp;
+
+                       sp = lookup($1, 0);
+                       if (sp->sflags & SINLINE)
+                               inline_ref(sp);
+                       $$ = nametree(sp);
+                       if (sp->sflags & SDYNARRAY)
                                $$ = buildtree(UMUL, $$, NIL);
                }
                |  C_ICON { $$ = $1; }
                |  C_FCON { $$ = $1; }
-               |  string {  $$ = strend(0, $1); /* get string contents */ }
-               |  wstring { $$ = strend('L', $1); }
+               |  string {  $$ = strend(widestr, $1); }
                |   '('  e  ')' { $$=$2; }
                ;
 
 clbrace:          '{'  { $$ = clbrace($<nodep>-1); }
                ;
 
-string:                   C_STRING {
-                       int len = strlen($1) + 1;
-                       $$ = tmpalloc(len);
-                       strlcpy($$, $1, len);
-               }
-               |  string C_STRING { 
-                       int len = strlen($1) + strlen($2) + 1;
-                       $$ = tmpalloc(len);
-                       strlcpy($$, $1, len);
-                       strlcat($$, $2, len);
-               }
-               ;
-
-wstring:         C_WSTRING {
-                       int len = strlen($1) + 1;
-                       $$ = tmpalloc(len);
-                       strlcpy($$, $1, len);
-               }
-               |  string C_WSTRING { 
-                       int len = strlen($1) + strlen($2) + 1;
-                       $$ = tmpalloc(len);
-                       strlcpy($$, $1, len);
-                       strlcat($$, $2, len);
-               }
+string:                   C_STRING { widestr = $1[0] == 'L'; $$ = stradd("", $1); }
+               |  string C_STRING { $$ = stradd($1, $2); }
                ;
 
 cast_type:        specifier_qualifier_list {
@@ -1117,8 +1043,7 @@ funct_idn:           C_NAME  '(' {
                        }
                        if (s->sflags & SINLINE)
                                inline_ref(s);
-                       spname = s;
-                       $$ = buildtree(NAME, NIL, NIL);
+                       $$ = nametree(s);
                }
                |  term  '(' 
                ;
@@ -1138,7 +1063,7 @@ bdty(int op, ...)
        register NODE *q;
 
        va_start(ap, op);
-       q = block(op, NIL, NIL, INT, 0, MKSUE(INT));
+       q = biop(op, NIL, NIL);
 
        switch (op) {
        case UMUL:
@@ -1154,9 +1079,11 @@ bdty(int op, ...)
 
        case LB:
                q->n_left = va_arg(ap, NODE *);
-               if ((val = va_arg(ap, int)) < 0)
-                       uerror("array size must be non-negative");
-               q->n_right = bcon(val < 0 ? 1 : val);
+               if ((val = va_arg(ap, int)) <= 0) {
+                       uerror("array size must be positive");
+                       val = 1;
+               }
+               q->n_right = bcon(val);
                break;
 
        case NAME:
@@ -1171,6 +1098,25 @@ bdty(int op, ...)
        return q;
 }
 
+static void
+flend(void)
+{
+       if (sspflag && blevel == 2)
+               sspend();
+#ifdef STABS
+       if (gflag && blevel > 2)
+               stabs_rbrac(blevel);
+#endif
+       --blevel;
+       if( blevel == 1 )
+               blevel = 0;
+       symclear(blevel); /* Clean ut the symbol table */
+       if (autooff > maxautooff)
+               maxautooff = autooff;
+       autooff = savctx->contlab;
+       savctx = savctx->next;
+}
+
 static void
 savebc(void)
 {
@@ -1221,14 +1167,15 @@ addcase(NODE *p)
                return;
        }
 
-       val = p->n_lval;
-       p = makety(p, swpole->type, 0, 0, MKSUE(swpole->type));
-       if (p->n_op != ICON)
-               cerror("could not cast case value to type of switch "
-                      "expression");
-       if (p->n_lval != val)
-               werror("case expression truncated");
-
+       if (DEUNSIGN(swpole->type) != DEUNSIGN(p->n_type)) {
+               val = p->n_lval;
+               p = makety(p, swpole->type, 0, 0, MKSUE(swpole->type));
+               if (p->n_op != ICON)
+                       cerror("could not cast case value to type of switch "
+                              "expression");
+               if (p->n_lval != val)
+                       werror("case expression truncated");
+       }
        sw->sval = p->n_lval;
        tfree(p);
        put = &swpole->ents;
@@ -1369,6 +1316,24 @@ init_declarator(NODE *tn, NODE *p, int assign)
        return typ->n_sp;
 }
 
+/*
+ * Declare function arguments.
+ */
+static void
+funargs(NODE *p)
+{
+       if (p->n_op == ELLIPSIS)
+               return;
+       if (oldstyle) {
+               p->n_op = TYPE;
+               p->n_type = FARG;
+       }
+       p->n_sp = lookup((char *)p->n_sp, 0);/* XXX */
+       if (ISFTN(p->n_type))
+               p->n_type = INCREF(p->n_type);
+       defid(p, PARAM);
+}
+
 /*
  * Declare a function.
  */
@@ -1381,17 +1346,25 @@ fundef(NODE *tp, NODE *p)
        int class = tp->n_lval, oclass;
        char *c;
 
-       while (q->n_op == UMUL)
-               q = q->n_left;
+       for (q = p; coptype(q->n_op) != LTYPE && q->n_left->n_op != NAME;
+           q = q->n_left)
+               ;
        if (q->n_op != CALL && q->n_op != UCALL) {
                uerror("invalid function definition");
                p = bdty(UCALL, p);
        }
 
-       /* Save function args before they are clobbered in tymerge() */
-       /* Typecheck against prototype will be done in defid(). */
-       ftnarg(p);
+       argoff = ARGINIT;
+       ctval = tvaloff;
+       blevel++;
+
+       if (q->n_op == CALL && q->n_right->n_type != VOID) {
+               /* declare function arguments */
+               listf(q->n_right, funargs);
+               ftnarg(q);
+       }
 
+       blevel--;
        tymerge(tp, p);
        s = p->n_sp = lookup((char *)p->n_sp, 0); /* XXX */
 
@@ -1399,14 +1372,17 @@ fundef(NODE *tp, NODE *p)
        if (class == STATIC && oclass == EXTERN)
                werror("%s was first declared extern, then static", s->sname);
 
-       if ((oclass == SNULL || oclass == USTATIC) &&
-           class == STATIC && fun_inline) {
+       if (fun_inline) {
+               /* special syntax for inline functions */
+               if ((oclass == SNULL || oclass == USTATIC) &&
+                   (class == STATIC || class == SNULL)) {
                /* Unreferenced, store it for (eventual) later use */
                /* Ignore it if it not declared static */
-               s->sflags |= SINLINE;
-               inline_start(s);
-       }
-       if (class == EXTERN)
+                       s->sflags |= SINLINE;
+                       inline_start(s);
+               } else if (class == EXTERN)
+                       class = EXTDEF;
+       } else if (class == EXTERN)
                class = SNULL; /* same result */
 
        cftnsp = s;
@@ -1442,7 +1418,7 @@ structref(NODE *p, int f, char *name)
 
        if (f == DOT)
                p = buildtree(ADDROF, p, NIL);
-       r = block(NAME, NIL, NIL, INT, 0, MKSUE(INT));
+       r = biop(NAME, NIL, NIL);
        r->n_name = name;
        r = buildtree(STREF, p, r);
        return r;
@@ -1468,7 +1444,7 @@ void
 branch(int lbl)
 {
        int r = reached++;
-       ecomp(block(GOTO, bcon(lbl), NIL, INT, 0, 0));
+       ecomp(biop(GOTO, bcon(lbl), NIL));
        reached = r;
 }
 
@@ -1481,7 +1457,7 @@ mkpstr(char *str)
        char *s, *os;
        int v, l = strlen(str)+3; /* \t + \n + \0 */
 
-       os = s = isinlining ? permalloc(l) : tmpalloc(l);
+       os = s = inlalloc(l);
        *s++ = '\t';
        for (; *str; ) {
                if (*str++ == '\\')
@@ -1495,6 +1471,81 @@ mkpstr(char *str)
        return os;
 }
 
+/*
+ * Estimate the max length a string will have in its internal 
+ * representation based on number of \ characters.
+ */
+static int
+maxstlen(char *str)
+{
+       int i;
+
+       for (i = 0; *str; str++, i++)
+               if (*str == '\\' || *str < 32 || *str > 0176)
+                       i += 3;
+       return i;
+}
+
+static char *
+voct(char *d, unsigned int v)
+{
+       v &= (1 << SZCHAR) - 1;
+       *d++ = '\\';
+       *d++ = v/64 + '0'; v &= 077;
+       *d++ = v/8 + '0'; v &= 7;
+       *d++ = v + '0';
+       return d;
+}
+       
+
+/*
+ * Convert a string to internal format.  The resulting string may be no
+ * more than len characters long.
+ */
+static void
+fixstr(char *d, char *s, int len)
+{
+       unsigned int v;
+
+       while (*s) {
+               if (len <= 0)
+                       cerror("fixstr");
+               if (*s == '\\') {
+                       s++;
+                       v = esccon(&s);
+                       d = voct(d, v);
+                       len -= 4;
+               } else if (*s < ' ' || *s > 0176) {
+                       d = voct(d, *s++);
+                       len -= 4;
+               } else
+                       *d++ = *s++, len--;
+       }
+       *d = 0;
+}
+
+/*
+ * Add "raw" string new to cleaned string old.
+ */
+static char *
+stradd(char *old, char *new)
+{
+       char *rv;
+       int len;
+
+       if (*new == 'L' && new[1] == '\"')
+               widestr = 1, new++;
+       if (*new == '\"') {
+               new++;                   /* remove first " */
+               new[strlen(new) - 1] = 0;/* remove last " */
+       }
+       len = strlen(old) + maxstlen(new) + 1;
+       rv = tmpalloc(len);
+       strlcpy(rv, old, len);
+       fixstr(rv + strlen(old), new, maxstlen(new) + 1);
+       return rv;
+}
+
 static struct symtab *
 clbrace(NODE *p)
 {
@@ -1509,7 +1560,7 @@ clbrace(NODE *p)
        sp->sdf = p->n_df;
        sp->ssue = p->n_sue;
        sp->sclass = blevel ? AUTO : STATIC;
-       if (!ISARY(sp->stype) || sp->sdf->ddim != 0) {
+       if (!ISARY(sp->stype) || sp->sdf->ddim != NOOFFSET) {
                sp->soffset = NOOFFSET;
                oalloc(sp, &autooff);
        }
@@ -1518,12 +1569,16 @@ clbrace(NODE *p)
        return sp;
 }
 
-/* Support for extended assembler a' la' gcc style follows below */
+NODE *
+biop(int op, NODE *l, NODE *r)
+{
+       return block(op, l, r, INT, 0, MKSUE(INT));
+}
 
 static NODE *
 cmop(NODE *l, NODE *r)
 {
-       return block(CM, l, r, INT, 0, MKSUE(INT));
+       return biop(CM, l, r);
 }
 
 static NODE *
@@ -1532,6 +1587,8 @@ voidcon(void)
        return block(ICON, NIL, NIL, STRTY, 0, MKSUE(VOID));
 }
 
+/* Support for extended assembler a' la' gcc style follows below */
+
 static NODE *
 xmrg(NODE *out, NODE *in)
 {
@@ -1560,10 +1617,10 @@ xcmop(NODE *out, NODE *in, NODE *str)
                /* D out-list sanity check */
                for (p = out; p->n_op == CM; p = p->n_left) {
                        q = p->n_right;
-                       if (q->n_name[0] != '=')
+                       if (q->n_name[0] != '=' && q->n_name[0] != '+')
                                uerror("output missing =");
                }
-               if (p->n_name[0] != '=')
+               if (p->n_name[0] != '=' && p->n_name[0] != '+')
                        uerror("output missing =");
                if (in == NIL)
                        p = out;
@@ -1586,8 +1643,8 @@ static NODE *
 xasmop(char *str, NODE *p)
 {
 
-       p = block(XARG, p, NIL, INT, 0, MKSUE(INT));
-       p->n_name = str;
+       p = biop(XARG, p, NIL);
+       p->n_name = isinlining ? newstring(str, strlen(str)+1) : str;
        return p;
 }
 
@@ -1599,8 +1656,8 @@ mkxasm(char *str, NODE *p)
 {
        NODE *q;
 
-       q = block(XASM, p->n_left, p->n_right, INT, 0, MKSUE(INT));
-       q->n_name = str;
+       q = biop(XASM, p->n_left, p->n_right);
+       q->n_name = isinlining ? newstring(str, strlen(str)+1) : str;
        nfree(p);
        ecomp(q);
 }
index 1f89206..d743f06 100644 (file)
@@ -1,4 +1,4 @@
-/*      $OpenBSD: gcc_compat.c,v 1.5 2008/04/11 20:45:52 stefan Exp $     */
+/*      $OpenBSD: gcc_compat.c,v 1.6 2008/08/17 18:40:12 ragge Exp $     */
 /*
  * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -44,13 +44,17 @@ static struct kw {
  * Do NOT change the order of these entries unless you know 
  * what you're doing!
  */
-       { "__asm", NULL, C_ASM },
-       { "__signed", NULL, 0 },
-       { "__inline", NULL, C_FUNSPEC },
-       { "__const", NULL, 0 },
-       { "__asm__", NULL, C_ASM },
-       { "__inline__", NULL, C_FUNSPEC },
-       { "__thread", NULL, 0 },
+/* 0 */        { "__asm", NULL, C_ASM },
+/* 1 */        { "__signed", NULL, 0 },
+/* 2 */        { "__inline", NULL, C_FUNSPEC },
+/* 3 */        { "__const", NULL, 0 },
+/* 4 */        { "__asm__", NULL, C_ASM },
+/* 5 */        { "__inline__", NULL, C_FUNSPEC },
+/* 6 */        { "__thread", NULL, 0 },
+/* 7 */        { "__FUNCTION__", NULL, 0 },
+/* 8 */        { "__volatile", NULL, 0 },
+/* 9 */        { "__volatile__", NULL, 0 },
+/* 10 */{ "__restrict", NULL, -1 },
        { NULL, NULL, 0 },
 };
 
@@ -96,6 +100,17 @@ gcc_keyword(char *str, NODE **n)
                while (tw > tlbuf)
                        cunput(*--tw);
                return -1;
+       case 7: /* __FUNCTION__ */
+               if (cftnsp == NULL) {
+                       uerror("__FUNCTION__ outside function");
+                       yylval.strp = "";
+               } else
+                       yylval.strp = cftnsp->sname; /* XXX - not C99 */
+               return C_STRING;
+       case 8: /* __volatile */
+       case 9: /* __volatile__ */
+               *n = block(QUALIFIER, NIL, NIL, VOL, 0, 0);
+               return C_QUALIFIER;
        }
        cerror("gcc_keyword");
        return 0;
index f4ced79..b6754d5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: init.c,v 1.7 2008/04/11 20:45:52 stefan Exp $ */
+/*     $OpenBSD: init.c,v 1.8 2008/08/17 18:40:12 ragge Exp $  */
 
 /*
  * Copyright (c) 2004, 2007 Anders Magnusson (ragge@ludd.ltu.se).
@@ -297,7 +297,8 @@ stkpush(void)
                is->in_lnk = ISSOU(DECREF(t)) ? pstk->in_sym->ssue->sylnk : 0;
                is->in_t = DECREF(t);
                is->in_sym = sp;
-               if (pstk->in_df->ddim && pstk->in_n >= pstk->in_df->ddim) {
+               if (pstk->in_df->ddim != NOOFFSET &&
+                   pstk->in_n >= pstk->in_df->ddim) {
                        werror("excess of initializing elements");
                        pstk->in_n--;
                }
@@ -340,7 +341,7 @@ stkpop(void)
                        pstk->in_n++;
                        if (pstk->in_fl)
                                break;
-                       if (pstk->in_df->ddim == 0 ||
+                       if (pstk->in_df->ddim == NOOFFSET ||
                            pstk->in_n < pstk->in_df->ddim)
                                break; /* ger more elements */
                }
@@ -401,10 +402,12 @@ findoff(void)
                        }
                }
        }
+#ifdef PCC_DEBUG
        if (idebug>1) {
                printf("findoff: off %lld\n", off);
                prtstk(pstk);
        }
+#endif
        return off;
 }
 
@@ -539,9 +542,7 @@ insbf(OFFSZ off, int fsz, int val)
        else
                typ = INT;
        /* Fake a struct reference */
-       spname = csym;
-       p = buildtree(ADDROF,
-           buildtree(NAME, NIL, NIL), NIL);
+       p = buildtree(ADDROF, nametree(csym), NIL);
        sym.stype = typ;
        sym.squal = 0;
        sym.sdf = 0;
@@ -598,7 +599,7 @@ endinit(void)
                defloc(csym);
 
        /* Calculate total block size */
-       if (ISARY(csym->stype) && csym->sdf->ddim == 0) {
+       if (ISARY(csym->stype) && csym->sdf->ddim == NOOFFSET) {
                tbit = numents*basesz; /* open-ended arrays */
                csym->sdf->ddim = numents;
                if (csym->sclass == AUTO) { /* Get stack space */
@@ -630,9 +631,7 @@ endinit(void)
                                            (ll->begsz + il->off) - lastoff);
 
                                /* Fake a struct reference */
-                               spname = csym;
-                               p = buildtree(ADDROF,
-                                   buildtree(NAME, NIL, NIL), NIL);
+                               p = buildtree(ADDROF, nametree(csym), NIL);
                                n = il->n;
                                sym.stype = n->n_type;
                                sym.squal = n->n_qual;
@@ -642,7 +641,7 @@ endinit(void)
                                sym.sclass = fsz < 0 ? FIELD | -fsz : 0;
                                r = xbcon(0, &sym, INT);
                                p = block(STREF, p, r, INT, 0, MKSUE(INT));
-                               ecode(buildtree(ASSIGN, stref(p), il->n));
+                               ecomp(buildtree(ASSIGN, stref(p), il->n));
                                if (fsz < 0)
                                        fsz = -fsz;
 
@@ -917,7 +916,7 @@ simpleinit(struct symtab *sp, NODE *p)
                /* Handle "aaa" as { 'a', 'a', 'a' } */
                beginit(sp);
                strcvt(p);
-               if (csym->sdf->ddim == 0)
+               if (csym->sdf->ddim == NOOFFSET)
                        scalinit(bcon(0)); /* Null-term arrays */
                endinit();
                return;
@@ -926,8 +925,7 @@ simpleinit(struct symtab *sp, NODE *p)
        switch (sp->sclass) {
        case STATIC:
        case EXTDEF:
-               spname = sp;
-               p = optim(buildtree(ASSIGN, buildtree(NAME, NIL, NIL), p));
+               p = optim(buildtree(ASSIGN, nametree(sp), p));
                defloc(sp);
                ninval(0, p->n_right->n_sue->suesize, p->n_right);
                tfree(p);
@@ -937,8 +935,7 @@ simpleinit(struct symtab *sp, NODE *p)
        case REGISTER:
                if (ISARY(sp->stype))
                        cerror("no array init");
-               spname = sp;
-               ecomp(buildtree(ASSIGN, buildtree(NAME, NIL, NIL), p));
+               ecomp(buildtree(ASSIGN, nametree(sp), p));
                break;
 
        default:
index de88379..f0bc7df 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: main.c,v 1.5 2008/04/11 20:45:52 stefan Exp $ */
+/*     $OpenBSD: main.c,v 1.6 2008/08/17 18:40:13 ragge Exp $  */
 
 /*
  * Copyright (c) 2002 Anders Magnusson. All rights reserved.
@@ -26,6 +26,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "config.h"
+
 #include <unistd.h>
 #include <signal.h>
 #include <string.h>
@@ -41,12 +43,19 @@ int iTflag, oTflag;
 #endif
 int xdebug, sdebug, gflag, c2debug, pdebug;
 int Wstrict_prototypes, Wmissing_prototypes, Wimplicit_int,
-       Wimplicit_function_declaration;
+       Wimplicit_function_declaration, Wpointer_sign, Wshadow,
+       Wsign_compare, Wunknown_pragmas, Wunreachable_code;
+#ifdef CHAR_UNSIGNED
+int funsigned_char = 1;
+#else
+int funsigned_char = 0;
+#endif
+int sspflag;
 int xssaflag, xtailcallflag, xtemps, xdeljumps;
 
 int e2debug, t2debug, f2debug, b2debug;
 
-struct suedef btdims[24];
+struct suedef btdims[32];
 char *prgname;
 
 static void prtstats(void);
@@ -58,6 +67,11 @@ static struct {
        { "missing-prototypes", &Wmissing_prototypes, },
        { "implicit-int", &Wimplicit_int, },
        { "implicit-function-declaration", &Wimplicit_function_declaration, },
+       { "shadow", &Wshadow, },
+       { "pointer-sign", &Wpointer_sign, },
+       { "sign-compare", &Wsign_compare, },
+       { "unknown-pragmas", &Wunknown_pragmas, },
+       { "unreachable-code", &Wunreachable_code, },
        { NULL, NULL, },
 };
 
@@ -86,26 +100,60 @@ segvcatch(int a)
 static void
 Wflags(char *str)
 {
-       int i, found = 0, all;
+       int i, flagval = 1, found = 0, all;
+
+       if (strncmp("no-", str, 3) == 0) {
+               str += 3;
+               flagval = 0;
+       }
 
        if (strcmp(str, "implicit") == 0) {
-               Wimplicit_int = Wimplicit_function_declaration = 1;
+               Wimplicit_int = Wimplicit_function_declaration = flagval;
                return;
        }
        if (strcmp(str, "error") == 0) {
-               warniserr = 1;
+               warniserr = flagval;
                return;
        }
+
        all = strcmp(str, "W") == 0;
-       for (i = 0; flagstr[i].n; i++)
+       for (i = 0; flagstr[i].n; i++) {
                if (all || strcmp(flagstr[i].n, str) == 0) {
-                       *flagstr[i].f = 1;
+                       *flagstr[i].f = flagval;
                        found++;
                }
-       if (found == 0)
+       }
+       if (found == 0) {
+               fprintf(stderr, "unrecognised option '%s'\n", str);
                usage();
+       }
 }
 
+static void
+fflags(char *str)
+{
+       int flagval = 1;
+
+       if (strncmp("no-", str, 3) == 0) {
+               str += 3;
+               flagval = 0;
+       }
+
+       if (strcmp(str, "signed-char") == 0)
+               funsigned_char = !flagval;
+       else if (strcmp(str, "unsigned-char") == 0)
+               funsigned_char = flagval;
+       else if (strcmp(str, "stack-protector") == 0)
+               sspflag = flagval;
+       else if (strcmp(str, "stack-protector-all") == 0)
+               sspflag = flagval;
+       else if (strncmp(str, "pack-struct", 11) == 0)
+               pragma_allpacked = (strlen(str) > 12 ? atoi(str+12) : 1);
+       else {
+               fprintf(stderr, "unrecognised option '%s'\n", str);
+               usage();
+       }
+}
 
 /* control multiple files */
 int
@@ -116,7 +164,7 @@ main(int argc, char *argv[])
 
        prgname = argv[0];
 
-       while ((ch = getopt(argc, argv, "OT:VW:X:Z:gklm:psvwx:")) != -1)
+       while ((ch = getopt(argc, argv, "OT:VW:X:Z:f:gklm:psvwx:")) != -1)
                switch (ch) {
 #if !defined(MULTIPASS) || defined(PASS1)
                case 'X':
@@ -190,22 +238,26 @@ main(int argc, char *argv[])
 #endif
                        break;
 
+               case 'f': /* Language */
+                       fflags(optarg);
+                       break;
+
+               case 'g': /* Debugging */
+                       gflag = 1;
+                       break;
+
                case 'k': /* PIC code */
                        ++kflag;
                        break;
 
-               case 'l': /* linenos */
+               case 'l': /* Linenos */
                        ++lflag;
                        break;
 
-               case 'm': /* target-specific */
+               case 'm': /* Target-specific */
                        mflags(optarg);
                        break;
 
-               case 'g': /* Debugging */
-                       gflag = 1;
-                       break;
-
                case 'p': /* Profiling */
                        pflag = 1;
                        break;
@@ -241,20 +293,21 @@ main(int argc, char *argv[])
                argc -= optind;
                argv += optind;
 
-               if (argc != 0) {
+               if (argc > 0 && strcmp(argv[0], "-") != 0) {
                        if (freopen(argv[0], "r", stdin) == NULL) {
                                fprintf(stderr, "open input file '%s':",
                                    argv[0]);
                                perror(NULL);
                                exit(1);
                        }
-                       if (argc != 1)
-                               if (freopen(argv[1], "w", stdout) == NULL) {
-                                       fprintf(stderr, "open output file '%s':",
-                                           argv[1]);
-                                       perror(NULL);
-                                       exit(1);
-                               }
+               }
+               if (argc > 1 && strcmp(argv[1], "-") != 0) {
+                       if (freopen(argv[1], "w", stdout) == NULL) {
+                               fprintf(stderr, "open output file '%s':",
+                                   argv[1]);
+                               perror(NULL);
+                               exit(1);
+                       }
                }
 
        mkdope();
@@ -282,6 +335,9 @@ main(int argc, char *argv[])
        btdims[UNSIGNED].suesize = SZINT;
        btdims[ULONG].suesize = SZLONG;
        btdims[ULONGLONG].suesize = SZLONGLONG;
+       btdims[FCOMPLEX].suesize = SZFLOAT * 2;
+       btdims[COMPLEX].suesize = SZDOUBLE * 2;
+       btdims[LCOMPLEX].suesize = SZLDOUBLE * 2;
        /* starts past any of the above */
        reached = 1;
 
@@ -294,6 +350,9 @@ main(int argc, char *argv[])
        }
 #endif
 
+       if (sspflag)
+               sspinit();
+
        (void) yyparse();
        yyaccpt();
 
index 6ae9991..5489125 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: optim.c,v 1.3 2008/04/11 20:45:52 stefan Exp $        */
+/*     $OpenBSD: optim.c,v 1.4 2008/08/17 18:40:13 ragge Exp $ */
 /*
  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
  *
@@ -135,7 +135,8 @@ again:      o = p->n_op;
                goto setuleft;
 
        case RS:
-               if (LO(p) == RS && RCON(p->n_left) && RCON(p)) {
+               if (LO(p) == RS && RCON(p->n_left) && RCON(p) &&
+                   (RV(p) + RV(p->n_left)) < p->n_sue->suesize) {
                        /* two right-shift  by constants */
                        RV(p) += RV(p->n_left);
                        p->n_left = zapleft(p->n_left);
index 960e0f4..51b00cc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pass1.h,v 1.9 2008/04/11 20:45:52 stefan Exp $        */
+/*     $OpenBSD: pass1.h,v 1.10 2008/08/17 18:40:13 ragge Exp $        */
 /*
  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
  *
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "config.h"
+
 #include <sys/types.h>
 #include <stdarg.h>
+#ifdef HAVE_STDINT_H
 #include <stdint.h>
+#endif
 
 #include "manifest.h"
 
@@ -82,14 +86,14 @@ extern      char *scnames(int);
 #define        NSTYPES         05
 #define        SMASK           07
 
-#define SSET           00010
-#define SREF           00020
-#define SNOCREAT       00040
-#define STEMP          00100
-#define        SDYNARRAY       00200
-#define        SINLINE         00400
-#define        STNODE          01000
-#define        SASG            04000
+/* #define SSET                00010 */
+/* #define SREF                00020 */
+#define SNOCREAT       00040   /* don't create a symbol in lookup() */
+#define STEMP          00100   /* Allocate symtab from temp or perm mem */
+#define        SDYNARRAY       00200   /* symbol is dynamic array on stack */
+#define        SINLINE         00400   /* function is of type inline */
+#define        STNODE          01000   /* symbol shall be a temporary node */
+#define        SASG            04000   /* symbol is assigned to already */
 #define        SLOCAL1         010000
 #define        SLOCAL2         020000
 #define        SLOCAL3         040000
@@ -192,10 +196,6 @@ extern     OFFSZ inoff;
 extern int reached;
 extern int isinlining;
 
-/*     tunnel to buildtree for name id's */
-
-extern struct symtab *spname;
-
 extern int sdebug, idebug, pdebug;
 
 /* various labels */
@@ -205,7 +205,7 @@ extern      int flostat;
 extern int retlab;
 
 /* pragma globals */
-extern int pragma_packed, pragma_aligned;
+extern int pragma_allpacked, pragma_packed, pragma_aligned;
 extern char *pragma_renamed;
 
 /*
@@ -222,12 +222,12 @@ extern char *pragma_renamed;
 
 /* declarations of various functions */
 extern NODE
-       *buildtree(int, NODE *l, NODE *r),
+       *buildtree(int, NODE *, NODE *r),
        *mkty(unsigned, union dimfun *, struct suedef *),
        *rstruct(char *, int),
        *dclstruct(struct rstack *),
        *strend(int gtype, char *),
-       *tymerge(NODE *typ, NODE *idp),
+       *tymerge(NODE *, NODE *),
        *stref(NODE *),
        *offcon(OFFSZ, TWORD, union dimfun *, struct suedef *),
        *bcon(int),
@@ -239,14 +239,14 @@ extern    NODE
        *ptmatch(NODE *),
        *tymatch(NODE *),
        *makety(NODE *, TWORD, TWORD, union dimfun *, struct suedef *),
-       *block(int, NODE *, NODE *r, TWORD, union dimfun *, struct suedef *),
+       *block(int, NODE *, NODE *, TWORD, union dimfun *, struct suedef *),
        *doszof(NODE *),
        *talloc(void),
        *optim(NODE *),
        *clocal(NODE *),
        *ccopy(NODE *),
-       *tempnode(int, TWORD type, union dimfun *df, struct suedef *sue),
-       *doacall(NODE *f, NODE *a);
+       *tempnode(int, TWORD, union dimfun *, struct suedef *),
+       *doacall(NODE *, NODE *);
 NODE   *intprom(NODE *);
 OFFSZ  tsize(TWORD, union dimfun *, struct suedef *),
        psize(NODE *);
@@ -255,56 +255,58 @@ void      spalloc(NODE *, NODE *, OFFSZ);
 char   *exname(char *);
 extern struct rstack *rpole;
 
-int oalloc(struct symtab *p, int *poff);
+int oalloc(struct symtab *, int *);
 void deflabel(char *);
 void gotolabel(char *);
-unsigned int esccon(char **sptr);
-void inline_start(struct symtab *sp);
+unsigned int esccon(char **);
+void inline_start(struct symtab *);
 void inline_end(void);
 void inline_addarg(struct interpass *);
-void inline_ref(struct symtab *sp);
+void inline_ref(struct symtab *);
 void inline_prtout(void);
 void ftnarg(NODE *);
 struct rstack *bstruct(char *, int);
 void moedef(char *);
 void beginit(struct symtab *);
 void simpleinit(struct symtab *, NODE *);
-struct symtab *lookup(char *name, int s);
-struct symtab *getsymtab(char *name, int flags);
+struct symtab *lookup(char *, int);
+struct symtab *getsymtab(char *, int);
 char *addstring(char *);
 char *addname(char *);
-char *newstring(char *, int len);
-void symclear(int level);
-struct symtab *hide(struct symtab *p);
+void symclear(int);
+struct symtab *hide(struct symtab *);
 void soumemb(NODE *, char *, int);
 int talign(unsigned int, struct suedef *);
 void bfcode(struct symtab **, int);
 int chkftn(union arglist *, union arglist *);
 void branch(int);
-void cbranch(NODE *p, NODE *q);
+void cbranch(NODE *, NODE *);
 void extdec(struct symtab *);
 void defzero(struct symtab *);
-int falloc(struct symtab *p, int w, int new, NODE *pty);
+int falloc(struct symtab *, int, int, NODE *);
 TWORD ctype(TWORD);  
-void ninval(CONSZ off, int fsz, NODE *);
-void infld(CONSZ off, int fsz, CONSZ);
-void zbits(CONSZ off, int fsz);
-void instring(struct symtab *sp);
-void inwstring(struct symtab *sp);
-void plabel(int lab);
+void ninval(CONSZ, int, NODE *);
+void infld(CONSZ, int, CONSZ);
+void zbits(CONSZ, int);
+void instring(struct symtab *);
+void inwstring(struct symtab *);
+void plabel(int);
 void bjobcode(void);
 void ejobcode(int);
 void calldec(NODE *, NODE *);
 int cisreg(TWORD);
-char *tmpsprintf(char *fmt, ...);
-char *tmpvsprintf(char *fmt, va_list ap);
+char *tmpsprintf(char *, ...);
+char *tmpvsprintf(char *, va_list);
 void asginit(NODE *);
 void desinit(NODE *);
 void endinit(void);
+void sspinit(void);
+void sspstart(void);
+void sspend(void);
 void ilbrace(void);
 void irbrace(void);
-void scalinit(NODE *p);
-void p1print(char *fmt, ...);
+void scalinit(NODE *);
+void p1print(char *, ...);
 char *copst(int);
 int cdope(int);
 void myp2tree(NODE *);
@@ -317,12 +319,15 @@ NODE *enumref(char *);
 CONSZ icons(NODE *);
 int mypragma(char **);
 void fixdef(struct symtab *);
-int cqual(TWORD t, TWORD q);
+int cqual(TWORD, TWORD);
 void defloc(struct symtab *);
-int fldchk(int sz);
+int fldchk(int);
 int nncon(NODE *);
-void cunput(char c);
-
+void cunput(char);
+NODE *nametree(struct symtab *sp);
+void *inlalloc(int size);
+void pass1_lastchance(struct interpass *);
+void fldty(struct symtab *p);
 
 #ifdef GCC_COMPAT
 void gcc_init(void);
@@ -338,7 +343,7 @@ void stabs_lbrac(int);
 void stabs_func(struct symtab *);
 void stabs_newsym(struct symtab *);
 void stabs_chgsym(struct symtab *);
-void stabs_struct(struct symtab *p, struct suedef *sue);
+void stabs_struct(struct symtab *, struct suedef *);
 #endif
 
 #ifndef CHARCAST
@@ -387,7 +392,9 @@ void stabs_struct(struct symtab *p, struct suedef *sue);
  */
 #define SIGNED         (MAXTYPES+1)
 #define BOOL           (MAXTYPES+2)
-
+#define        FCOMPLEX        (MAXTYPES+3)
+#define        COMPLEX         (MAXTYPES+4)
+#define        LCOMPLEX        (MAXTYPES+5)
 
 #define coptype(o)     (cdope(o)&TYFLG)
 #define clogop(o)      (cdope(o)&LOGFLG)
index 55d2925..5f946d3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pftn.c,v 1.13 2008/04/11 20:45:52 stefan Exp $        */
+/*     $OpenBSD: pftn.c,v 1.14 2008/08/17 18:40:13 ragge Exp $ */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -71,7 +71,6 @@
 
 #include "cgram.h"
 
-struct symtab *spname;
 struct symtab *cftnsp;
 int arglistcnt, dimfuncnt;     /* statistics */
 int symtabcnt, suedefcnt;      /* statistics */
@@ -101,6 +100,8 @@ struct rstack {
        int     rstr;
        struct  symtab *rsym;
        struct  symtab *rb;
+       int     flags;
+#define        LASTELM 1
 } *rpole;
 
 /*
@@ -139,6 +140,7 @@ int ddebug = 0;
 void
 defid(NODE *q, int class)
 {
+       extern int fun_inline;
        struct symtab *p;
        TWORD type, qual;
        TWORD stp, stq;
@@ -151,6 +153,9 @@ defid(NODE *q, int class)
 
        p = q->n_sp;
 
+       if (p->sname == NULL)
+               cerror("defining null identifier");
+
 #ifdef PCC_DEBUG
        if (ddebug) {
                printf("defid(%s (%p), ", p->sname, p);
@@ -215,10 +220,11 @@ defid(NODE *q, int class)
        changed = 0;
        for (temp = type; temp & TMASK; temp = DECREF(temp)) {
                if (ISARY(temp)) {
-                       if (dsym->ddim == 0) {
+                       if (dsym->ddim == NOOFFSET) {
                                dsym->ddim = ddef->ddim;
                                changed = 1;
-                       } else if (ddef->ddim != 0 && dsym->ddim!=ddef->ddim) {
+                       } else if (ddef->ddim != NOOFFSET &&
+                           dsym->ddim!=ddef->ddim) {
                                goto mismatch;
                        }
                        ++dsym;
@@ -258,59 +264,60 @@ defid(NODE *q, int class)
                switch( scl ){
                case STATIC:
                case USTATIC:
-                       if( slev==0 ) return;
+                       if( slev==0 )
+                               goto done;
                        break;
                case EXTDEF:
                case EXTERN:
                case FORTRAN:
                case UFORTRAN:
-                       return;
+                       goto done;
                        }
                break;
 
        case STATIC:
                if (scl==USTATIC || (scl==EXTERN && blevel==0)) {
                        p->sclass = STATIC;
-                       return;
+                       goto done;
                }
                if (changed || (scl == STATIC && blevel == slev))
-                       return; /* identical redeclaration */
+                       goto done; /* identical redeclaration */
                break;
 
        case USTATIC:
                if (scl==STATIC || scl==USTATIC)
-                       return;
+                       goto done;
                break;
 
        case TYPEDEF:
                if (scl == class)
-                       return;
+                       goto done;
                break;
 
        case UFORTRAN:
                if (scl == UFORTRAN || scl == FORTRAN)
-                       return;
+                       goto done;
                break;
 
        case FORTRAN:
                if (scl == UFORTRAN) {
                        p->sclass = FORTRAN;
-                       return;
+                       goto done;
                }
                break;
 
        case MOU:
        case MOS:
-               return;
+               goto done;
 
        case EXTDEF:
                switch (scl) {
                case EXTERN:
                        p->sclass = EXTDEF;
-                       return;
+                       goto done;
                case USTATIC:
                        p->sclass = STATIC;
-                       return;
+                       goto done;
                }
                break;
 
@@ -318,7 +325,11 @@ defid(NODE *q, int class)
        case REGISTER:
                if (blevel == slev)
                        goto redec;
-               ;  /* mismatch.. */
+               break;  /* mismatch.. */
+       case SNULL:
+               if (fun_inline && ISFTN(type))
+                       goto done;
+               break;
        }
 
        mismatch:
@@ -396,11 +407,18 @@ redec:                    uerror("redeclaration of %s", p->sname);
                break;
 
        case MOU:
+               rpole->rstr = 0;
+               /* FALLTHROUGH */
        case MOS:
                oalloc(p, &rpole->rstr);
                if (class == MOU)
                        rpole->rstr = 0;
                break;
+       case SNULL:
+               if (fun_inline) {
+                       p->slevel = 1;
+                       p->soffset = getlab();
+               }
        }
 
 #ifdef STABS
@@ -408,6 +426,7 @@ redec:                      uerror("redeclaration of %s", p->sname);
                stabs_newsym(p);
 #endif
 
+done:
        fixdef(p);      /* Leave last word to target */
 #ifdef PCC_DEBUG
        if (ddebug)
@@ -705,6 +724,12 @@ enumref(char *name)
        NODE *p;
 
        sp = lookup(name, STAGNAME);
+       /*
+        * 6.7.2.3 Clause 2:
+        * "A type specifier of the form 'enum identifier' without an
+        *  enumerator list shall only appear after the type it specifies
+        *  is complete."
+        */
        if (sp->sclass != ENAME)
                uerror("enum %s undeclared", name);
 
@@ -735,9 +760,8 @@ bstruct(char *name, int soru)
        } else
                sp = NULL;
 
-       r = tmpalloc(sizeof(struct rstack));
+       r = tmpcalloc(sizeof(struct rstack));
        r->rsou = soru;
-       r->rstr = 0;
        r->rsym = sp;
        r->rb = NULL;
        r->rnext = rpole;
@@ -758,6 +782,9 @@ dclstruct(struct rstack *r)
        int al, sa, sz, coff;
        TWORD temp;
 
+       if (pragma_allpacked && !pragma_packed)
+               pragma_packed = pragma_allpacked;
+
        if (r->rsym == NULL) {
                sue = permalloc(sizeof(struct suedef));
                suedefcnt++;
@@ -768,10 +795,6 @@ dclstruct(struct rstack *r)
        if (sue->suealign == 0)  /* suealign == 0 is undeclared struct */
                sue->suealign = ALSTRUCT;
 
-#ifdef PCC_DEBUG
-       if (ddebug)
-               printf("dclstruct(%s)\n", r->rsym ? r->rsym->sname : "??");
-#endif
        temp = r->rsou == STNAME ? STRTY : UNIONTY;
        al = ALSTRUCT;
 
@@ -805,11 +828,21 @@ dclstruct(struct rstack *r)
                 */
                SETOFF(al, sa);
        }
-       SETOFF(rpole->rstr, al);
+
+       if (!pragma_packed && !pragma_aligned)
+               SETOFF(rpole->rstr, al);
 
        sue->suesize = rpole->rstr;
        sue->suealign = al;
 
+#ifdef PCC_DEBUG
+       if (ddebug) {
+               printf("dclstruct(%s): size=%d, align=%d\n",
+                   r->rsym ? r->rsym->sname : "??",
+                   sue->suesize, sue->suealign);
+       }
+#endif
+
        pragma_packed = pragma_aligned = 0;
 
 #ifdef STABS
@@ -839,6 +872,7 @@ void
 soumemb(NODE *n, char *name, int class)
 {
        struct symtab *sp, *lsp;
+       int incomp;
  
        if (rpole == NULL)
                cerror("soumemb");
@@ -854,10 +888,38 @@ soumemb(NODE *n, char *name, int class)
        else
                lsp->snext = sp;
        n->n_sp = sp;
+       if ((class & FIELD) == 0)
+               class = rpole->rsou == STNAME ? MOS : MOU;
        defid(n, class);
-}
 
+       /*
+        * 6.7.2.1 clause 16:
+        * "...the last member of a structure with more than one
+        *  named member may have incomplete array type;"
+        */
+       if (ISARY(sp->stype) && sp->sdf->ddim == NOOFFSET)
+               incomp = 1;
+       else
+               incomp = 0;
+       if ((rpole->flags & LASTELM) || (rpole->rb == sp && incomp == 1))
+               uerror("incomplete array in struct");
+       if (incomp == 1)
+               rpole->flags |= LASTELM;
+
+       /*
+        * 6.7.2.1 clause 2:
+        * "...such a structure shall not be a member of a structure
+        *  or an element of an array."
+        */
+       if (sp->stype == STRTY && sp->ssue->sylnk) {
+               struct symtab *lnk;
+
+               for (lnk = sp->ssue->sylnk; lnk->snext; lnk = lnk->snext)
+                       ;
+               if (ISARY(lnk->stype) && lnk->sdf->ddim == NOOFFSET)
+                       uerror("incomplete struct in struct");
+       }
+}
 
 /*
  * error printing routine in parser
@@ -1005,6 +1067,8 @@ tsize(TWORD ty, union dimfun *d, struct suedef *sue)
                case PTR:
                        return( SZPOINT(ty) * mult );
                case ARY:
+                       if (d->ddim == NOOFFSET)
+                               return 0;
                        mult *= d->ddim;
                        d++;
                        continue;
@@ -1035,7 +1099,7 @@ tsize(TWORD ty, union dimfun *d, struct suedef *sue)
 }
 
 /*
- * Save string (and print it out).  If wide == 'L' then wide string.
+ * Save string (and print it out).  If wide then wide string.
  */
 NODE *
 strend(int wide, char *str)
@@ -1044,7 +1108,7 @@ strend(int wide, char *str)
        NODE *p;
 
        /* If an identical string is already emitted, just forget this one */
-       if (wide == 'L') {
+       if (wide) {
                /* Do not save wide strings, at least not now */
                sp = getsymtab(str, SSTRING|STEMP);
        } else {
@@ -1061,24 +1125,24 @@ strend(int wide, char *str)
                sp->soffset = getlab();
                sp->squal = (CON >> TSHIFT);
                sp->sdf = permalloc(sizeof(union dimfun));
-               if (wide == 'L') {
+               if (wide) {
                        sp->stype = WCHAR_TYPE+ARY;
                        sp->ssue = MKSUE(WCHAR_TYPE);
                } else {
-#ifdef CHAR_UNSIGNED
-                       sp->stype = UCHAR+ARY;
-                       sp->ssue = MKSUE(UCHAR);
-#else
-                       sp->stype = CHAR+ARY;
-                       sp->ssue = MKSUE(CHAR);
-#endif
+                       if (funsigned_char) {
+                               sp->stype = UCHAR+ARY;
+                               sp->ssue = MKSUE(UCHAR);
+                       } else {
+                               sp->stype = CHAR+ARY;
+                               sp->ssue = MKSUE(CHAR);
+                       }
                }
                for (wr = sp->sname, i = 1; *wr; i++)
                        if (*wr++ == '\\')
                                (void)esccon(&wr);
 
                sp->sdf->ddim = i;
-               if (wide == 'L')
+               if (wide)
                        inwstring(sp);
                else
                        instring(sp);
@@ -1119,12 +1183,11 @@ oalloc(struct symtab *p, int *poff )
        /*
         * Only generate tempnodes if we are optimizing,
         * and only for integers, floats or pointers,
-        * and not if the basic type is volatile.
+        * and not if the type on this level is volatile.
         */
-/* XXX OLDSTYLE */
        if (xtemps && ((p->sclass == AUTO) || (p->sclass == REGISTER)) &&
            (p->stype < STRTY || ISPTR(p->stype)) &&
-           !ISVOL((p->squal << TSHIFT)) && cisreg(p->stype)) {
+           !(cqual(p->stype, p->squal) & VOL) && cisreg(p->stype)) {
                NODE *tn = tempnode(0, p->stype, p->sdf, p->ssue);
                p->soffset = regno(tn);
                p->sflags |= STNODE;
@@ -1209,7 +1272,7 @@ dynalloc(struct symtab *p, int *poff)
        astkp = 0;
        if (ISARY(t) && blevel == 1) {
                /* must take care of side effects of dynamic arg arrays */
-               if (p->sdf->ddim < 0) {
+               if (p->sdf->ddim < 0 && p->sdf->ddim != NOOFFSET) {
                        /* first-level array will be indexed correct */
                        edelay(arrstk[astkp++]);
                }
@@ -1235,8 +1298,10 @@ dynalloc(struct symtab *p, int *poff)
                        continue;
                if (df->ddim < 0) {
                        n = arrstk[astkp++];
-                       nn = tempnode(0, INT, 0, MKSUE(INT));
-                       no = regno(nn);
+                       do {
+                               nn = tempnode(0, INT, 0, MKSUE(INT));
+                               no = regno(nn);
+                       } while (no == -NOOFFSET);
                        edelay(buildtree(ASSIGN, nn, n));
 
                        df->ddim = -no;
@@ -1358,7 +1423,7 @@ nidcl(NODE *p, int class)
 
        sp = p->n_sp;
        /* check if forward decl */
-       if (ISARY(sp->stype) && sp->sdf->ddim == 0)
+       if (ISARY(sp->stype) && sp->sdf->ddim == NOOFFSET)
                return;
 
        if (sp->sflags & SASG)
@@ -1459,14 +1524,11 @@ typenode(NODE *p)
        NODE *q, *saved;
        TWORD type;
        int class, qual;
-       int sig, uns;
+       int sig, uns, cmplx;
 
-       type = class = qual = sig = uns = 0;
+       cmplx = type = class = qual = sig = uns = 0;
        saved = NIL;
 
-       if (rpole != NULL)
-               class = rpole->rsou == STNAME ? MOS : MOU;
-
        for (q = p; p; p = p->n_left) {
                switch (p->n_op) {
                case CLASS:
@@ -1544,11 +1606,32 @@ typenode(NODE *p)
                                        goto bad;
                                uns = 1;
                                break;
+                       case COMPLEX:
+                               cmplx = 1;
+                               break;
                        default:
                                cerror("typenode");
                        }
                }
        }
+       if (cmplx) {
+               if (sig || uns)
+                       goto bad;
+               switch (type) {
+               case FLOAT:
+                       type = FCOMPLEX;
+                       break;
+               case DOUBLE:
+                       type = COMPLEX;
+                       break;
+               case LDOUBLE:
+                       type = LCOMPLEX;
+                       break;
+               default:
+                       goto bad;
+               }
+       }
+
        if (saved && type)
                goto bad;
        if (sig || uns) {
@@ -1559,10 +1642,9 @@ typenode(NODE *p)
                if (uns)
                        type = ENUNSIGN(type);
        }
-#ifdef CHAR_UNSIGNED
-       if (type == CHAR && sig == 0)
+
+       if (funsigned_char && type == CHAR && sig == 0)
                type = UCHAR;
-#endif
 
        /* free the chain */
        while (q) {
@@ -1789,7 +1871,7 @@ tyreduce(NODE *p, struct tylnk **tylkp, int *ntdim)
                        nfree(p->n_right);
 #ifdef notdef
        /* XXX - check dimensions at usage time */
-                       if (dim.ddim == 0 && p->n_left->n_op == LB)
+                       if (dim.ddim == NOOFFSET && p->n_left->n_op == LB)
                                uerror("null dimension");
 #endif
                }
@@ -1859,6 +1941,22 @@ builtin_alloca(NODE *f, NODE *a)
        return u;
 }
 
+/*
+ * Determine if a value is known to be constant at compile-time and
+ * hence that PCC can perform constant-folding on expressions involving
+ * that value.
+ */
+static NODE *
+builtin_constant_p(NODE *f, NODE *a)
+{
+       int isconst = (a != NULL && a->n_op == ICON);
+
+       tfree(f);
+       tfree(a);
+
+       return bcon(isconst);
+}
+
 #ifndef TARGET_STDARGS
 static NODE *
 builtin_stdarg_start(NODE *f, NODE *a)
@@ -1966,6 +2064,7 @@ static struct bitable {
        NODE *(*fun)(NODE *f, NODE *a);
 } bitable[] = {
        { "__builtin_alloca", builtin_alloca },
+       { "__builtin_constant_p", builtin_constant_p },
 #ifndef TARGET_STDARGS
        { "__builtin_stdarg_start", builtin_stdarg_start },
        { "__builtin_va_arg", builtin_va_arg },
@@ -2051,7 +2150,7 @@ doacall(NODE *f, NODE *a)
            f->n_sp->sname[0] == '_' && f->n_sp->sname[1] == '_') {
                int i;
 
-               for (i = 0; i < sizeof(bitable)/sizeof(bitable[0]); i++) {
+               for (i = 0; i < (int)(sizeof(bitable)/sizeof(bitable[0])); i++) {
                        if (strcmp(bitable[i].name, f->n_sp->sname) == 0)
                                return (*bitable[i].fun)(f, a);
                }
@@ -2062,11 +2161,14 @@ doacall(NODE *f, NODE *a)
         */
        if (f->n_df == NULL || (al = f->n_df[0].dfun) == NULL) {
                if (Wimplicit_function_declaration) {
-                       if (f->n_sp != NULL)
-                               werror("no prototype for function '%s()'",
-                                   f->n_sp->sname);
-                       else
+                       if (f->n_sp != NULL) {
+                               if (strncmp(f->n_sp->sname,
+                                   "__builtin", 9) != 0)
+                                       werror("no prototype for function "
+                                           "'%s()'", f->n_sp->sname);
+                       } else {
                                werror("no prototype for function pointer");
+                       }
                }
                /* floats must be cast to double */
                if (a == NULL)
@@ -2144,8 +2246,19 @@ doacall(NODE *f, NODE *a)
                if ((hasarray = ISARY(arrt)))
                        arrt += (PTR-ARY);
 #endif
-               if (ISARY(type))
-                       type += (PTR-ARY);
+               /* Taking addresses of arrays are meaningless in expressions */
+               /* but people tend to do that and also use in prototypes */
+               /* this is mostly a problem with typedefs */
+               if (ISARY(type)) {
+                       if (ISPTR(arrt) && ISARY(DECREF(arrt)))
+                               type = INCREF(type);
+                       else
+                               type += (PTR-ARY);
+               } else if (ISPTR(type) && !ISARY(DECREF(type)) &&
+                   ISPTR(arrt) && ISARY(DECREF(arrt))) {
+                       type += (ARY-PTR);
+                       type = INCREF(type);
+               }
 
                /* Check structs */
                if (type <= BTMASK && arrt <= BTMASK) {
@@ -2190,9 +2303,9 @@ incomp:                                   uerror("incompatible types for arg %d",
                        goto skip; /* Anything assigned a zero */
 
                if ((type & ~BTMASK) == (arrt & ~BTMASK)) {
-                       /* do not complain for intermixed char/uchar */
-                       if ((BTYPE(type) == CHAR || BTYPE(type) == UCHAR) &&
-                           (BTYPE(arrt) == CHAR || BTYPE(arrt) == UCHAR))
+                       /* do not complain for pointers with signedness */
+                       if (!Wpointer_sign &&
+                           DEUNSIGN(BTYPE(type)) == DEUNSIGN(BTYPE(arrt)))
                                goto skip;
                }
 
@@ -2238,9 +2351,9 @@ chk2(TWORD type, union dimfun *dsym, union dimfun *ddef)
                switch (type & TMASK) {
                case ARY:
                        /* may be declared without dimension */
-                       if (dsym->ddim == 0)
+                       if (dsym->ddim == NOOFFSET)
                                dsym->ddim = ddef->ddim;
-                       if (ddef->ddim && dsym->ddim != ddef->ddim)
+                       if (ddef->ddim != NOOFFSET && dsym->ddim != ddef->ddim)
                                return 1;
                        dsym++, ddef++;
                        break;
@@ -2368,8 +2481,12 @@ uclass(int class)
 int
 fixclass(int class, TWORD type)
 {
+       extern int fun_inline;
+
        /* first, fix null class */
        if (class == SNULL) {
+               if (fun_inline && ISFTN(type))
+                       return SNULL;
                if (rpole)
                        class = rpole->rsou == STNAME ? MOS : MOU;
                else if (blevel == 0)
@@ -2398,7 +2515,7 @@ fixclass(int class, TWORD type)
                }
 
        if (class & FIELD) {
-               if (rpole && rpole->rsou != STNAME)
+               if (rpole && rpole->rsou != STNAME && rpole->rsou != UNAME)
                        uerror("illegal use of field");
                return(class);
        }
@@ -2508,7 +2625,7 @@ getsymtab(char *name, int flags)
 int
 fldchk(int sz)
 {
-       if (rpole->rsou != STNAME)
+       if (rpole->rsou != STNAME && rpole->rsou != UNAME)
                uerror("field outside of structure");
        if (sz < 0 || sz >= FIELD) {
                uerror("illegal field size");
@@ -2553,3 +2670,108 @@ scnames(int c)
        return( ccnames[c] );
        }
 #endif
+
+void
+sspinit()
+{
+       NODE *p;
+
+       p = block(NAME, NIL, NIL, FTN+VOID, 0, MKSUE(VOID));
+       p->n_sp = lookup("__stack_chk_fail", SNORMAL);
+       defid(p, EXTERN);
+       nfree(p);
+
+       p = block(NAME, NIL, NIL, INT, 0, MKSUE(INT));
+       p->n_sp = lookup("__stack_chk_guard", SNORMAL);
+       defid(p, EXTERN);
+       nfree(p);
+}
+
+void
+sspstart()
+{
+       NODE *p, *q;
+
+       q = block(NAME, NIL, NIL, INT, 0, MKSUE(INT));
+       q->n_sp = lookup("__stack_chk_guard", SNORMAL);
+       q = clocal(q);
+
+       p = block(REG, NIL, NIL, INT, 0, 0);
+       p->n_lval = 0;
+       p->n_rval = FPREG;
+       q = block(ER, p, q, INT, 0, MKSUE(INT));
+       q = clocal(q);
+
+       p = block(NAME, NIL, NIL, INT, 0, MKSUE(INT));
+       p->n_sp = lookup("__stack_chk_canary", SNORMAL);
+       defid(p, AUTO);
+       p = clocal(p);
+
+       ecomp(buildtree(ASSIGN, p, q));
+}
+
+void
+sspend()
+{
+       NODE *p, *q;
+       TWORD t;
+       int tmpnr = 0;
+       int lab;
+
+       if (retlab != NOLAB) {
+               plabel(retlab);
+               retlab = getlab();
+       }
+
+       t = DECREF(cftnsp->stype);
+       if (t == BOOL)
+               t = BOOL_TYPE;
+
+       if (t != VOID && !ISSOU(t)) {
+               p = tempnode(0, t, cftnsp->sdf, cftnsp->ssue);
+               tmpnr = regno(p);
+               q = block(REG, NIL, NIL, t, cftnsp->sdf, cftnsp->ssue);
+               q->n_rval = RETREG(t);
+               ecomp(buildtree(ASSIGN, p, q));
+       }
+
+       p = block(NAME, NIL, NIL, INT, 0, MKSUE(INT));
+       p->n_sp = lookup("__stack_chk_canary", SNORMAL);
+       p = clocal(p);
+
+       q = block(REG, NIL, NIL, INT, 0, 0);
+       q->n_lval = 0;
+       q->n_rval = FPREG;
+       q = block(ER, p, q, INT, 0, MKSUE(INT));
+
+       p = block(NAME, NIL, NIL, INT, 0, MKSUE(INT));
+       p->n_sp = lookup("__stack_chk_guard", SNORMAL);
+       p = clocal(p);
+
+       lab = getlab();
+       cbranch(buildtree(EQ, p, q), bcon(lab));
+
+       p = block(NAME, NIL, NIL, FTN+VOID, 0, MKSUE(VOID));
+       p->n_sp = lookup("__stack_chk_fail", SNORMAL);
+       p = clocal(p);
+
+       ecomp(buildtree(UCALL, p, NIL));
+
+       plabel(lab);
+
+       if (t != VOID && !ISSOU(t)) {
+               p = tempnode(tmpnr, t, cftnsp->sdf, cftnsp->ssue);
+               q = block(REG, NIL, NIL, t, cftnsp->sdf, cftnsp->ssue);
+               q->n_rval = RETREG(t);
+               ecomp(buildtree(ASSIGN, q, p));
+       }
+}
+
+/*
+ * Allocate on the permanent heap for inlines, otherwise temporary heap.
+ */
+void *
+inlalloc(int size)
+{
+       return isinlining ?  permalloc(size) : tmpalloc(size);
+}
index 32dd785..12feaaa 100644 (file)
@@ -1,5 +1,5 @@
 %{
-/*     $OpenBSD: scan.l,v 1.5 2008/04/11 20:45:52 stefan Exp $ */
+/*     $OpenBSD: scan.l,v 1.6 2008/08/17 18:40:13 ragge Exp $  */
 
 /*
  * Copyright (c) 2002 Anders Magnusson. All rights reserved.
@@ -38,6 +38,7 @@ FS                    (f|F|l|L)
 IS                     (u|U|l|L)*
 
 %{
+#include <stdlib.h>
 #include <errno.h>  
 #include <string.h>
 #include <stdarg.h>
@@ -58,20 +59,20 @@ int notype, parbal;
 #define        CPP_HASH        4
 
 #ifdef STABS
-#define        STABS_LINE(x) if (gflag && blevel > 1) stabs_line(x)
+#define        STABS_LINE(x) if (gflag && cftnsp) stabs_line(x)
 #else
 #define STABS_LINE(x)
 #endif
 #if defined(FLEX_SCANNER) && YY_FLEX_SUBMINOR_VERSION >= 31
-/* Hack to avoid unneccessary warnings */
+/* Hack to avoid unnecessary warnings */
 FILE *yyget_in  (void);
 FILE *yyget_out  (void);
 int yyget_leng  (void);
 char *yyget_text  (void);
-void yyset_in (FILE *  in_str );
-void yyset_out (FILE *  out_str );
+void yyset_in (FILE *);
+void yyset_out (FILE *);
 int yyget_debug  (void);
-void yyset_debug (int  bdebug );
+void yyset_debug (int);
 int yylex_destroy  (void);
 extern int yyget_lineno (void);
 extern void yyset_lineno (int);
@@ -95,6 +96,8 @@ extern void yyset_lineno (int);
 "case"                 { return(C_CASE); }
 "char"                 { yylval.nodep = mkty((TWORD)CHAR, 0, MKSUE(CHAR));
                          notype=1; return(C_TYPE); }
+"_Complex"             { yylval.nodep = mkty((TWORD)COMPLEX, 0, MKSUE(DOUBLE));
+                         notype=1; return(C_TYPE); }
 "const"                        { yylval.nodep =
                                block(QUALIFIER, NIL, NIL, CON, 0, 0);
                          return(C_QUALIFIER); }
@@ -167,19 +170,8 @@ L?'(\\.|[^\\'])+'  { yylval.nodep = charcon(); return(C_ICON); }
 0[xX]{H}+"."{P}{FS}?   { yylval.nodep = fhexcon(); return(C_FCON); }
 0[xX]{H}+{P}{FS}?      { yylval.nodep = fhexcon(); return(C_FCON); }
 
-L?\"(\\.|[^\\"])*\"    {
-                               char *c = yytext;
-                               int i = yyleng-2, rv;
-
-                               if (*c++ == 'L') {
-                                       c++, i--;
-                                       rv = C_WSTRING;
-                               } else
-                                       rv = C_STRING;
-                               c[i] = 0; /* last " */
-                               yylval.strp = c;
-                               return rv;
-                       }
+L?\"(\\.|[^\\"])*\"    { yylval.strp = yytext; return C_STRING; }
+
 "..."                  { return(C_ELLIPSIS); }
 ">>="                  { yylval.intval = RSEQ; return(C_ASOP); }
 "<<="                  { yylval.intval = LSEQ; return(C_ASOP); }
@@ -326,9 +318,13 @@ esccon(char **sptr)
        case '\"': val = '\"'; break;
        case 'x': val = strtoul(wr, &wr, 16); break;
        case '0': case '1': case '2': case '3': case '4': 
-       case '5': case '6': case '7': case '8': case '9': 
-               wr--;
-               val = strtoul(wr, &wr, 8);
+       case '5': case '6': case '7':
+               val = wr[-1] - '0';
+               if (*wr >= '0' && *wr <= '7') {
+                       val = (val << 3) + (*wr++ - '0');
+                       if (*wr >= '0' && *wr <= '7')
+                               val = (val << 3) + (*wr++ - '0');
+               }
                break;
        default: val = wr[-1];
        }
@@ -478,15 +474,17 @@ splitup(char *str)
 
        /* count ws. at least needed array size, add 2 to terminate */
        for (i = 2, s = str; *s; s++)
-               if (*s == ' ' || *s == '\t')
+               if (*s == ' ' || *s == '\t' ||
+                   *s == '(' || *s == ')' || *s == ',')
                        i++;
        ary = tmpalloc(sizeof(char *)*i);
-       for (i = 0, s = strtok(str, " \t"); s; s = strtok(NULL, " \t"))
+       for (i = 0, s = strtok(str, " \t(,)"); s; s = strtok(NULL, " \t(,)"))
                ary[i++] = s;
        ary[i] = NULL;
        return ary;
 }
 
+int pragma_allpacked;
 int pragma_packed, pragma_aligned;
 char *pragma_renamed;
 
@@ -501,16 +499,21 @@ pragma()
        ary = splitup(yytext);
        if (ary[1] == NULL)
                goto bad;
-       if (strcmp(ary[1], "packed") == 0) {
+       if (strcmp(ary[1], "pack") == 0) {
+               pragma_allpacked = ary[2] ? atoi(ary[2]) : 0;
+       } else if (strcmp(ary[1], "packed") == 0) {
                pragma_packed = ary[2] ? atoi(ary[2]) : 1;
        } else if (strcmp(ary[1], "aligned") == 0) {
                pragma_aligned = ary[2] ? atoi(ary[2]) : 1;
        } else if (strcmp(ary[1], "rename") == 0) {
                pragma_renamed = newstring(ary[2], strlen(ary[2]));
-       } else if (mypragma(ary))
+       } else if (mypragma(ary)) {
                return;
-       else
-bad:           werror("unknown pragma");
+       } else {
+bad:
+               if (Wunknown_pragmas)
+                       werror("unknown pragma");
+       }
 }
 
 void
index 7876554..e1e0551 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: stabs.c,v 1.7 2008/04/11 20:45:52 stefan Exp $        */
+/*     $OpenBSD: stabs.c,v 1.8 2008/08/17 18:40:13 ragge Exp $ */
 
 /*
  * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
@@ -308,6 +308,7 @@ printtype(struct symtab *s, char *ostr, int len)
 void
 stabs_newsym(struct symtab *s)
 {
+       extern int fun_inline;
        char *sname;
        char ostr[MAXPSTR];
        int suesize;
@@ -358,7 +359,10 @@ stabs_newsym(struct symtab *s)
                cprint(savestabs, "\t.stabs \"%s:r%s\",%d,0,%d,%d\n", sname, ostr,
                    N_RSYM, 1, s->soffset);
                break;
-
+       case SNULL:
+               if (fun_inline)
+                       break;
+               /* FALLTHROUGH */
        default:
                cerror("fix stab_newsym; class %d", s->sclass);
        }
@@ -389,6 +393,9 @@ cprint(int p2, char *fmt, ...)
        va_list ap;  
        char *str;
 
+       if (isinlining)
+               return; /* XXX do not save any inline functions currently */
+
        va_start(ap, fmt);
        if (p2) {
                str = tmpvsprintf(fmt, ap);
index 9f1b1a0..f66e5b2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: symtabs.c,v 1.4 2008/01/07 21:04:47 stefan Exp $      */
+/*     $OpenBSD: symtabs.c,v 1.5 2008/08/17 18:40:13 ragge Exp $       */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -29,6 +29,8 @@
 
 #include "pass1.h"
 
+#include <stdint.h>
+
 /*
  * These definitions are used in the patricia tree that stores
  * the strings.
@@ -175,7 +177,7 @@ int numsyms[NSTYPES];
  * Returns a struct symtab.
  */
 struct symtab *
-lookup(char *key, int ttype)
+lookup(char *key, int stype)
 {
        struct symtab *sym;
        struct tree *w, *new, *last;
@@ -183,7 +185,7 @@ lookup(char *key, int ttype)
        int type, uselvl;
        intptr_t ix, match, code = (intptr_t)key;
 
-       type = ttype & SMASK;
+       type = stype & SMASK;
        uselvl = (blevel > 0 && type != SSTRING);
 
        /*
@@ -197,15 +199,15 @@ lookup(char *key, int ttype)
 
        switch (numsyms[type]) {
        case 0:
-               if (ttype & SNOCREAT)
+               if (stype & SNOCREAT)
                        return NULL;
                if (uselvl) {
-                       sym = getsymtab(key, ttype|STEMP);
+                       sym = getsymtab(key, stype|STEMP);
                        sym->snext = tmpsyms[type];
                        tmpsyms[type] = sym;
                        return sym;
                }
-               sympole[type] = (struct tree *)getsymtab(key, ttype);
+               sympole[type] = (struct tree *)getsymtab(key, stype);
                numsyms[type]++;
                return (struct symtab *)sympole[type];
 
@@ -233,7 +235,7 @@ lookup(char *key, int ttype)
        ix = code ^ match;
        if (ix == 0)
                return sym;
-       else if (ttype & SNOCREAT)
+       else if (stype & SNOCREAT)
                return NULL;
 
 #ifdef PCC_DEBUG
@@ -246,7 +248,7 @@ lookup(char *key, int ttype)
         * Insert into the linked list, if feasible.
         */
        if (uselvl) {
-               sym = getsymtab(key, ttype|STEMP);
+               sym = getsymtab(key, stype|STEMP);
                sym->snext = tmpsyms[type];
                tmpsyms[type] = sym;
                return sym;
@@ -258,17 +260,17 @@ lookup(char *key, int ttype)
         * This could be optimized by adding a remove routine, but it
         * may be more trouble than it is worth.
         */
-       if (ttype == (STEMP|SNORMAL))
-               ttype = SNORMAL;
+       if (stype == (STEMP|SNORMAL))
+               stype = SNORMAL;
 
        for (cix = 0; (ix & 1) == 0; ix >>= 1, cix++)
                ;
 
-       new = ttype & STEMP ? tmpalloc(sizeof(struct tree)) :
+       new = stype & STEMP ? tmpalloc(sizeof(struct tree)) :
            permalloc(sizeof(struct tree));
        bit = (code >> cix) & 1;
        new->bitno = cix | (bit ? RIGHT_IS_LEAF : LEFT_IS_LEAF);
-       new->lr[bit] = (struct tree *)getsymtab(key, ttype);
+       new->lr[bit] = (struct tree *)getsymtab(key, stype);
        if (numsyms[type]++ == 1) {
                new->lr[!bit] = sympole[type];
                new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF);
@@ -348,6 +350,10 @@ hide(struct symtab *sym)
        new = getsymtab(sym->sname, typ|STEMP);
        new->snext = tmpsyms[typ];
        tmpsyms[typ] = new;
+
+       if (Wshadow)
+               werror("declaration of '%s' shadows previous", sym->sname);
+
 #ifdef PCC_DEBUG
        if (ddebug)
                printf("\t%s hidden at level %d (%p -> %p)\n",
index e7bd9a8..bfe4290 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: trees.c,v 1.14 2008/04/11 20:45:52 stefan Exp $       */
+/*     $OpenBSD: trees.c,v 1.15 2008/08/17 18:40:13 ragge Exp $        */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -197,9 +197,11 @@ buildtree(int o, NODE *l, NODE *r)
                case ER:
                case LS:
                case RS:
-                       if( conval( l, o, r ) ) {
-                               nfree(r);
-                               return(l);
+                       if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) {
+                               if( conval( l, o, r ) ) {
+                                       nfree(r);
+                                       return(l);
+                               }
                        }
                        break;
                }
@@ -296,51 +298,7 @@ runtime:
                switch(o){
 
                case NAME:
-                       sp = spname;
-                       if (sp->sflags & STNODE) {
-                               /* Generated for optimizer */
-                               p->n_op = TEMP;
-                               p->n_type = sp->stype;
-                               p->n_sue = sp->ssue;
-                               p->n_df = sp->sdf;
-                               p->n_rval = sp->soffset;
-                               break;
-                       }
-                               
-#ifdef GCC_COMPAT
-                       /* Get a label name */
-                       if (sp->sflags == SLBLNAME) {
-                               p->n_type = VOID;
-                               p->n_sue = MKSUE(VOID);
-                               p->n_lval = 0;
-                               p->n_sp = sp;
-                               break;
-                       } else
-#endif
-                       if (sp->stype == UNDEF) {
-                               uerror("%s undefined", sp->sname);
-                               /* make p look reasonable */
-                               p->n_type = INT;
-                               p->n_sue = MKSUE(INT);
-                               p->n_df = NULL;
-                               p->n_sp = sp;
-                               p->n_lval = 0;
-                               defid(p, SNULL);
-                               break;
-                       }
-                       p->n_type = sp->stype;
-                       p->n_qual = sp->squal;
-                       p->n_df = sp->sdf;
-                       p->n_sue = sp->ssue;
-                       p->n_lval = 0;
-                       p->n_sp = sp;
-                       if (sp->sclass == MOE) {
-                               p->n_op = ICON;
-                               p->n_lval = sp->soffset;
-                               p->n_df = NULL;
-                               p->n_sp = NULL;
-                       }
-                       break;
+                       cerror("buildtree NAME");
 
                case STREF:
                        /* p->x turned into *(p+offset) */
@@ -352,16 +310,20 @@ runtime:
                                break;
                        }
 
-                       if ((sp = l->n_sue->sylnk) == NULL)
+                       if ((sp = l->n_sue->sylnk) == NULL) {
                                uerror("undefined struct or union");
+                               break;
+                       }
 
                        name = r->n_name;
                        for (; sp != NULL; sp = sp->snext) {
                                if (sp->sname == name)
                                        break;
                        }
-                       if (sp == NULL)
+                       if (sp == NULL) {
                                uerror("member '%s' not declared", name);
+                               break;
+                       }
 
                        r->n_sp = sp;
                        p = stref(p);
@@ -540,6 +502,55 @@ runtime:
 
        }
 
+/*
+ * Build a name node based on a symtab entry.
+ * broken out from buildtree().
+ */
+NODE *
+nametree(struct symtab *sp)
+{
+       NODE *p;
+
+       p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->ssue);
+       p->n_qual = sp->squal;
+       p->n_sp = sp;
+
+#ifndef NO_C_BUILTINS
+       if (sp->sname[0] == '_' && strncmp(sp->sname, "__builtin_", 10) == 0)
+               return p;  /* do not touch builtins here */
+       
+#endif
+
+       if (sp->sflags & STNODE) {
+               /* Generated for optimizer */
+               p->n_op = TEMP;
+               p->n_rval = sp->soffset;
+       }
+
+#ifdef GCC_COMPAT
+       /* Get a label name */
+       if (sp->sflags == SLBLNAME) {
+               p->n_type = VOID;
+               p->n_sue = MKSUE(VOID);
+       }
+#endif
+       if (sp->stype == UNDEF) {
+               uerror("%s undefined", sp->sname);
+               /* make p look reasonable */
+               p->n_type = INT;
+               p->n_sue = MKSUE(INT);
+               p->n_df = NULL;
+               defid(p, SNULL);
+       }
+       if (sp->sclass == MOE) {
+               p->n_op = ICON;
+               p->n_lval = sp->soffset;
+               p->n_df = NULL;
+               p->n_sp = NULL;
+       }
+       return clocal(p);
+}
+
 /*
  * Do a conditional branch.
  */
@@ -797,7 +808,8 @@ chkpun(NODE *p)
                        t1 = DECREF(t1);
                        t2 = DECREF(t2);
                }
-               werror("illegal pointer combination");
+               if (Wpointer_sign)
+                       werror("illegal pointer combination");
        }
 }
 
@@ -1159,6 +1171,10 @@ tymatch(p)  register NODE *p; {
                t2 = DEUNSIGN(t2);
                }
 
+       if (Wsign_compare && clogop(o) && t1 == t2 && lu != ru &&
+           p->n_left->n_op != ICON && p->n_right->n_op != ICON)
+               werror("comparison between signed and unsigned");
+
 #if 0
        if ((t1 == CHAR || t1 == SHORT) && o!= RETURN)
                t1 = INT;
@@ -1566,6 +1582,8 @@ doszof(NODE *p)
        df = p->n_df;
        ty = p->n_type;
        while (ISARY(ty)) {
+               if (df->ddim == NOOFFSET)
+                       uerror("sizeof of incomplete type");
                rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) :
                    tempnode(-df->ddim, INT, 0, MKSUE(INT)));
                df++;
@@ -1933,7 +1951,7 @@ delasgop(NODE *p)
        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.
+                * Pass2 will remove -1 if unnecessary.
                 */
                q = ccopy(p);
                tfree(p->n_left);
@@ -1991,7 +2009,8 @@ ecomp(NODE *p)
                fwalk(p, eprint, 0);
 #endif
        if (!reached) {
-               werror("statement not reached");
+               if (Wunreachable_code)
+                       werror("statement not reached");
                reached = 1;
        }
        p = optim(p);
@@ -2003,6 +2022,7 @@ ecomp(NODE *p)
                ecode(p);
 }
 
+
 #if defined(MULTIPASS)
 void   
 p2tree(NODE *p)
@@ -2075,6 +2095,17 @@ p2tree(NODE *p)
                p2tree(p->n_right);
 }
 #else
+static char *
+sptostr(struct symtab *sp)
+{
+       char *cp = inlalloc(32);
+       int n = sp->soffset;
+       if (n < 0)
+               n = -n;
+       snprintf(cp, 32, LABFMT, n);
+       return cp;
+}
+
 void
 p2tree(NODE *p)
 {
@@ -2095,16 +2126,16 @@ p2tree(NODE *p)
                            q->sflags == SLBLNAME ||
 #endif
                            q->sclass == ILABEL) {
-                               char *cp = (isinlining ?
-                                   permalloc(32) : tmpalloc(32));
-                               int n = q->soffset;
-                               if (n < 0)
-                                       n = -n;
-                               snprintf(cp, 32, LABFMT, n);
+                               p->n_name = sptostr(q);
+                       } else if (!kflag) {
+                               char *name = exname(q->soname);
+                               int n = strlen(name) + 1;
+                               char *cp = inlalloc(n);
+
+                               strlcpy(cp, name, n);
                                p->n_name = cp;
-                       } else {
+                       } else
                                p->n_name = q->soname;
-                       }
                } else
                        p->n_name = "";
                break;
@@ -2130,6 +2161,18 @@ p2tree(NODE *p)
                p->n_stsize = (tsize(STRTY, p->n_left->n_df,
                    p->n_left->n_sue)+SZCHAR-1)/SZCHAR;
                p->n_stalign = talign(STRTY,p->n_left->n_sue)/SZCHAR;
+               /* FALLTHROUGH */
+       case CALL:
+       case UCALL:
+               if (callop(p->n_op) && p->n_left->n_op == ICON &&
+                   (q = p->n_left->n_sp) != NULL && q->sclass == SNULL &&
+                   (q->sflags & SINLINE)) {
+                       /* call to inline ftns uses L-style labels */
+                       p->n_left->n_name = sptostr(q);
+                       if (ty == BITYPE)
+                               p2tree(p->n_right);
+                       return;
+               }
                break;
 
        case XARG:
@@ -2219,7 +2262,7 @@ send_passt(int type, ...)
        else
                sz = sizeof(struct interpass);
 
-       ip = isinlining ? permalloc(sz) : tmpalloc(sz);
+       ip = inlalloc(sz);
        ip->type = type;
        ip->lineno = lineno;
        switch (type) {
@@ -2249,7 +2292,9 @@ send_passt(int type, ...)
                break;
        case IP_ASM:
                if (blevel == 0) { /* outside function */
-                       printf("\t%s\n", va_arg(ap, char *));
+                       printf("\t");
+                       printf("%s", va_arg(ap, char *));
+                       printf("\n");
                        va_end(ap);
                        defloc(NULL);
                        return;
@@ -2260,6 +2305,7 @@ send_passt(int type, ...)
                cerror("bad send_passt type %d", type);
        }
        va_end(ap);
+       pass1_lastchance(ip); /* target-specific info */
        if (isinlining)
                inline_addarg(ip);
        else
index 47f4ced..c2b9e47 100644 (file)
@@ -1,8 +1,12 @@
-/*     $OpenBSD: config.h,v 1.5 2008/04/11 20:45:51 stefan Exp $       */
+/*     $OpenBSD: config.h,v 1.6 2008/08/17 18:40:12 ragge Exp $        */
 
 #define PCC_MAJOR 0
 #define PCC_MINOR 9
 #define PCC_MINORMINOR 9
-#define VERSSTR "pcc 0.9.9"
+#define        PACKAGE_VERSION "0.9.9"
+#define VERSSTR "pcc " PACKAGE_VERSION
+#define        PACKAGE_STRING  VERSSTR
+#define        TARGOS OpenBSD
 
 #define YYTEXT_POINTER 1
+#define        HAVE_CPP_VARARG_MACRO_GCC
index 0c849dc..9d8f972 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: cpp.1,v 1.5 2008/04/11 20:55:22 stefan Exp $
+.\"    $OpenBSD: cpp.1,v 1.6 2008/08/17 18:40:13 ragge Exp $
 ."\
 .\" Copyright (c) 2007 Jeremy C. Reed <reed@reedmedia.net>
 .\"
@@ -102,6 +102,9 @@ Include a file at the beginning by using
 Generate dependencies for
 .Xr make 1 .
 .\" TODO: explain and show example?
+.It Fl P
+Inhibit generation of line markers.  This is sometimes useful when
+running the preprocessor on something other than C code.
 .It Fl S Ar path
 Add
 .Ar path
index 095b75d..3e435ac 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpp.c,v 1.9 2008/04/11 20:45:52 stefan Exp $  */
+/*     $OpenBSD: cpp.c,v 1.10 2008/08/17 18:40:13 ragge Exp $  */
 
 /*
  * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
@@ -99,12 +99,15 @@ int dflag;  /* debug printouts */
 #define DDPRINT(x)
 #endif
 
+#define GCC_VARI
+
 int ofd;
 usch outbuf[CPPBUF];
 int obufp, istty, inmac;
-int Cflag, Mflag, dMflag;
+int Cflag, Mflag, dMflag, Pflag;
 usch *Mfile;
 struct initar *initar;
+int readmac;
 
 /* avoid recursion */
 struct recur {
@@ -145,6 +148,7 @@ usch *stringbuf = sbf;
  *   1->   - number of args.
  */
 
+#define        GCCARG  0xfd    /* has gcc varargs that may be replaced with 0 */
 #define        VARG    0xfe    /* has varargs */
 #define        OBJCT   0xff
 #define        WARN    1       /* SOH, not legal char */
@@ -152,6 +156,8 @@ usch *stringbuf = sbf;
 #define        SNUFF   3       /* ETX, not legal char */
 #define        NOEXP   4       /* EOT, not legal char */
 #define        EXPAND  5       /* ENQ, not legal char */
+#define        PRAGS   6       /* start of converted pragma */
+#define        PRAGE   14      /* end of converted pragma */
 
 /* args for lookup() */
 #define        FIND    0
@@ -164,6 +170,9 @@ void include(void);
 void line(void);
 void flbuf(void);
 void usage(void);
+usch *xstrdup(char *str);
+usch *prtprag(usch *opb);
+
 
 int
 main(int argc, char **argv)
@@ -173,7 +182,7 @@ main(int argc, char **argv)
        struct symtab *nl;
        register int ch;
 
-       while ((ch = getopt(argc, argv, "CD:I:MS:U:d:i:tvV?")) != -1)
+       while ((ch = getopt(argc, argv, "CD:I:MPS:U:d:i:tvV?")) != -1)
                switch (ch) {
                case 'C': /* Do not discard comments */
                        Cflag++;
@@ -195,6 +204,10 @@ main(int argc, char **argv)
                        Mflag++;
                        break;
 
+               case 'P': /* Inhibit generation of line numbers */
+                       Pflag++;
+                       break;
+
                case 'S':
                case 'I':
                        if ((w = calloc(sizeof(struct incs), 1)) == NULL)
@@ -315,6 +328,7 @@ gotident(struct symtab *nl)
 
        thisnl = NULL;
        slow = 1;
+       readmac++;
        base = osp = stringbuf;
        goto found;
 
@@ -377,6 +391,10 @@ found:                     if (nl == 0 || subst(nl, NULL) == 0) {
                        thisnl = NULL;
                        break;
 
+               case CMNT:
+                       getcmnt();
+                       break;
+
                case STRING:
                case '\n':
                case NUMBER:
@@ -394,11 +412,12 @@ found:                    if (nl == 0 || subst(nl, NULL) == 0) {
                }
                if (thisnl == NULL) {
                        slow = 0;
+                       readmac--;
                        savch(0);
                        return base;
                }
        }
-       error("preamture EOF");
+       error("premature EOF");
        /* NOTREACHED */
        return NULL; /* XXX gcc */
 }
@@ -549,6 +568,55 @@ definp(void)
        return c;
 }
 
+void
+getcmnt(void)
+{
+       int c;
+
+       savstr((usch *)yytext);
+       for (;;) {
+               c = cinput();
+               if (c == '*') {
+                       c = cinput();
+                       if (c == '/') {
+                               savstr((usch *)"*/");
+                               return;
+                       }
+                       cunput(c);
+                       c = '*';
+               }
+               savch(c);
+       }
+}
+
+/*
+ * Compare two replacement lists, taking in account comments etc.
+ */
+static int
+cmprepl(usch *o, usch *n)
+{
+       for (; *o; o--, n--) {
+               /* comment skip */
+               if (*o == '/' && o[-1] == '*') {
+                       while (*o != '*' || o[-1] != '/')
+                               o--;
+                       o -= 2;
+               }
+               if (*n == '/' && n[-1] == '*') {
+                       while (*n != '*' || n[-1] != '/')
+                               n--;
+                       n -= 2;
+               }
+               while (*o == ' ' || *o == '\t')
+                       o--;
+               while (*n == ' ' || *n == '\t')
+                       n--;
+               if (*o != *n)
+                       return 1;
+       }
+       return 0;
+}
+
 void
 define()
 {
@@ -557,7 +625,10 @@ define()
        int c, i, redef;
        int mkstr = 0, narg = -1;
        int ellips = 0;
-       size_t len;
+#ifdef GCC_VARI
+       usch *gccvari = NULL;
+       int wascon;
+#endif
 
        if (flslvl)
                return;
@@ -571,6 +642,7 @@ define()
        np = lookup((usch *)yytext, ENTER);
        redef = np->value != NULL;
 
+       readmac = 1;
        sbeg = stringbuf;
        if ((c = yylex()) == '(') {
                narg = 0;
@@ -591,15 +663,20 @@ define()
                                        if (!strcmp((char *) args[i], yytext))
                                                error("Duplicate macro "
                                                  "parameter \"%s\"", yytext);
-                               len = strlen(yytext);
-                               args[narg] = alloca(len+1);
-                               strlcpy((char *)args[narg], yytext, len+1);
-                               narg++;
+                               args[narg++] = xstrdup(yytext);
                                if ((c = definp()) == ',') {
                                        if ((c = definp()) == ')')
                                                goto bad;
                                        continue;
                                }
+#ifdef GCC_VARI
+                               if (c == ELLIPS) {
+                                       if (definp() != ')')
+                                               goto bad;
+                                       gccvari = args[--narg];
+                                       break;
+                               }
+#endif
                                if (c == ')')
                                        break;
                        }
@@ -622,6 +699,10 @@ define()
        /* parse replacement-list, substituting arguments */
        savch('\0');
        while (c != '\n') {
+#ifdef GCC_VARI
+               wascon = 0;
+loop:
+#endif
                switch (c) {
                case WSPACE:
                        /* remove spaces if it surrounds a ## directive */
@@ -633,6 +714,12 @@ define()
                                savch(CONC);
                                if ((c = yylex()) == WSPACE)
                                        c = yylex();
+#ifdef GCC_VARI
+                               if (c == '\n')
+                                       break;
+                               wascon = 1;
+                               goto loop;
+#endif
                        }
                        continue;
 
@@ -641,7 +728,14 @@ define()
                        savch(CONC);
                        if ((c = yylex()) == WSPACE)
                                c = yylex();
+#ifdef GCC_VARI
+                       if (c == '\n')
+                               break;
+                       wascon = 1;
+                       goto loop;
+#else
                        continue;
+#endif
 
                case MKSTR:
                        if (narg < 0) {
@@ -666,6 +760,16 @@ define()
                                if (strcmp(yytext, (char *)args[i]) == 0)
                                        break;
                        if (i == narg) {
+#ifdef GCC_VARI
+                               if (gccvari &&
+                                   strcmp(yytext, (char *)gccvari) == 0) {
+                                       savch(wascon ? GCCARG : VARG);
+                                       savch(WARN);
+                                       if (mkstr)
+                                               savch(SNUFF), mkstr = 0;
+                                       break;
+                               }
+#endif
                                if (mkstr)
                                        error("not argument");
                                goto id;
@@ -685,12 +789,17 @@ define()
                                savch(SNUFF), mkstr = 0;
                        break;
 
+               case CMNT: /* save comments */
+                       getcmnt();
+                       break;
+
                default:
 id:                    savstr((usch *)yytext);
                        break;
                }
                c = yylex();
        }
+       readmac = 0;
        /* remove trailing whitespace */
        while (stringbuf > sbeg) {
                if (stringbuf[-1] == ' ' || stringbuf[-1] == '\t')
@@ -701,18 +810,19 @@ id:                       savstr((usch *)yytext);
                else
                        break;
        }
+#ifdef GCC_VARI
+       if (gccvari) {
+               savch(narg);
+               savch(VARG);
+       } else
+#endif
        if (ellips) {
                savch(narg);
                savch(VARG);
        } else
                savch(narg < 0 ? OBJCT : narg);
        if (redef) {
-               usch *o = np->value, *n = stringbuf-1;
-
-               /* Redefinition to identical replacement-list is allowed */
-               while (*o && *o == *n)
-                       o--, n--;
-               if (*o || *o != *n)
+               if (cmprepl(np->value, stringbuf-1))
                        error("%s redefined\nprevious define: %s:%d",
                            np->namep, np->file, np->line);
                stringbuf = sbeg;  /* forget this space */
@@ -740,6 +850,8 @@ id:                 savstr((usch *)yytext);
        }
 #endif
        slow = 0;
+       for (i = 0; i < narg; i++)
+               free(args[i]);
        return;
 
 bad:   error("bad define");
@@ -801,8 +913,7 @@ pragoper(void)
        usch *opb;
        int t, plev;
 
-       slow = 1;
-       putstr((usch *)"\n#pragma ");
+       slow++;
        if ((t = yylex()) == WSPACE)
                t = yylex();
        if (t != '(')
@@ -828,23 +939,19 @@ pragoper(void)
        cunput('\n');
        while (stringbuf > opb)
                cunput(*--stringbuf);
+       savch(PRAGS);
        while ((t = yylex()) != '\n') {
                if (t == WSPACE)
                        continue;
                if (t != STRING)
                        goto bad;
-               opb = (usch *)yytext;
-               if (*opb++ == 'L')
-                       opb++;
-               while ((t = *opb++) != '\"') {
-                       if (t == '\\' && (*opb == '\"' || *opb == '\\'))
-                               t = *opb++;
-                       putch(t);
-               }
+               savstr((usch *)yytext);
        }
 
-       putch('\n');
-       prtline();
+       savch(PRAGE);
+       while (stringbuf > opb)
+               cunput(*--stringbuf);
+       slow--;
        return;
 bad:   error("bad pragma operator");
 }
@@ -946,7 +1053,6 @@ expmac(struct recur *rp)
        struct symtab *nl;
        int c, noexp = 0, orgexp;
        usch *och, *stksv;
-       extern int yyleng;
 
 #ifdef CPP_DEBUG
        if (dflag) {
@@ -958,6 +1064,7 @@ expmac(struct recur *rp)
                }
        }
 #endif
+       readmac++;
        while ((c = yylex()) != WARN) {
                switch (c) {
                case NOEXP: noexp++; break;
@@ -1018,6 +1125,8 @@ expmac(struct recur *rp)
                        unpstr((usch *)yytext);
                        if (orgexp == -1)
                                cunput(EXPAND);
+                       else if (orgexp == -2)
+                               cunput(EXPAND), cunput(EXPAND);
                        else if (orgexp == 1)
                                cunput(NOEXP);
                        unpstr(och);
@@ -1048,8 +1157,7 @@ expmac(struct recur *rp)
                                error("bad noexp %d", noexp);
                        stksv = NULL;
                        if ((c = yylex()) == WSPACE) {
-                               stksv = alloca(yyleng+1);
-                               strlcpy((char *)stksv, yytext, yyleng+1);
+                               stksv = xstrdup(yytext);
                                c = yylex();
                        }
                        /* only valid for expansion if fun macro */
@@ -1066,6 +1174,12 @@ expmac(struct recur *rp)
                                        unpstr(stksv);
                                savstr(nl->namep);
                        }
+                       if (stksv)
+                               free(stksv);
+                       break;
+
+               case CMNT:
+                       getcmnt();
                        break;
 
                case STRING:
@@ -1087,6 +1201,7 @@ def:              default:
        }
        if (noexp)
                error("expmac noexp=%d", noexp);
+       readmac--;
        DPRINT(("return from expmac\n"));
 }
 
@@ -1113,7 +1228,8 @@ expdef(vp, rp, gotwarn)
                ellips = 1;
        } else
                narg = vp[1];
-       args = alloca(sizeof(usch *) * (narg+ellips));
+       if ((args = malloc(sizeof(usch *) * (narg+ellips))) == NULL)
+               error("expdef: out of mem");
 
        /*
         * read arguments and store them on heap.
@@ -1142,8 +1258,14 @@ expdef(vp, rp, gotwarn)
                        savstr((usch *)yytext);
                        while ((c = yylex()) == '\n')
                                savch('\n');
+                       while (c == CMNT) {
+                               getcmnt();
+                               c = yylex();
+                       }
                        if (c == EXPAND)
                                instr = 0;
+                       if (c == 0)
+                               error("eof in macro");
                }
                while (args[i] < stringbuf &&
                    (stringbuf[-1] == ' ' || stringbuf[-1] == '\t'))
@@ -1216,6 +1338,14 @@ expdef(vp, rp, gotwarn)
                        if (sp[-1] == VARG) {
                                bp = ap = args[narg];
                                sp--;
+#ifdef GCC_VARI
+                       } else if (sp[-1] == GCCARG) {
+                               ap = args[narg];
+                               if (ap[0] == 0)
+                                       ap = (usch *)"0";
+                               bp = ap;
+                               sp--;
+#endif
                        } else
                                bp = ap = args[(int)*--sp];
                        if (sp[2] != CONC && !snuff && sp[-1] != CONC) {
@@ -1261,6 +1391,7 @@ expdef(vp, rp, gotwarn)
 
        /* scan the input buffer (until WARN) and save result on heap */
        expmac(rp);
+       free(args);
 }
 
 usch *
@@ -1324,6 +1455,10 @@ void
 putstr(usch *s)
 {
        for (; *s; s++) {
+               if (*s == PRAGS) {
+                       s = prtprag(s);
+                       continue;
+               }
                outbuf[obufp++] = *s;
                if (obufp == CPPBUF || (istty && *s == '\n'))
                        flbuf();
@@ -1549,3 +1684,41 @@ lookup(usch *key, int enterf)
        return (struct symtab *)new->lr[bit];
 }
 
+usch *
+xstrdup(char *str)
+{
+       size_t len = strlen(str)+1;
+       usch *rv;
+
+       if ((rv = malloc(len)) == NULL)
+               error("xstrdup: out of mem");
+       strlcpy((char *)rv, str, len);
+       return rv;
+}
+
+usch *
+prtprag(usch *s)
+{
+       int ch;
+
+       s++;
+       putstr((usch *)"\n#pragma ");
+       while (*s != PRAGE) {
+               if (*s == 'L')
+                       s++;
+               if (*s == '\"') {
+                       s++;
+                       while ((ch = *s++) != '\"') {
+                               if (ch == '\\' && (*s == '\"' || *s == '\\'))
+                                       ch = *s++;
+                               putch(ch);
+                       }
+               } else {
+                       s++;
+                       putch(*s);
+               }
+       }
+       putstr((usch *)"\n");
+       prtline();
+       return ++s;
+}
index 8b94abe..d0a84fb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpp.h,v 1.5 2007/10/21 18:58:02 otto Exp $    */
+/*     $OpenBSD: cpp.h,v 1.6 2008/08/17 18:40:13 ragge Exp $   */
 
 /*
  * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
@@ -43,7 +43,7 @@ extern        int     trulvl;
 extern int     flslvl;
 extern int     elflvl;
 extern int     elslvl;
-extern int     tflag, Cflag;
+extern int     tflag, Cflag, Pflag;
 extern int     Mflag, dMflag;
 extern usch    *Mfile;
 extern int     ofd;
@@ -72,6 +72,7 @@ struct includ {
        int infil;
        usch *curptr;
        usch *maxread;
+       usch *ostr;
        usch *buffer;
        usch bbuf[NAMEMAX+CPPBUF+1];
 } *ifiles;
@@ -134,6 +135,13 @@ void line(void);
 usch *sheap(char *fmt, ...);
 void xwarning(usch *);
 void xerror(usch *);
+#ifdef HAVE_CPP_VARARG_MACRO_GCC
 #define warning(...) xwarning(sheap(__VA_ARGS__))
 #define error(...) xerror(sheap(__VA_ARGS__))
+#else
+#define warning printf
+#define error printf
+#endif
 void expmac(struct recur *);
+int cinput(void);
+void getcmnt(void);
index c4ff140..a49a9c8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpy.y,v 1.4 2007/10/21 18:58:02 otto Exp $    */
+/*     $OpenBSD: cpy.y,v 1.5 2008/08/17 18:40:13 ragge Exp $   */
 
 /*
  * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
@@ -87,7 +87,7 @@ int setd(int l, int r);
 /*
  * The following terminals are not used in the yacc code.
  */
-%term STRING FPOINT WSPACE VA_ARGS CONCAT MKSTR ELLIPS
+%term STRING FPOINT WSPACE VA_ARGS CONCAT MKSTR ELLIPS CMNT
 
 %left ','
 %right '?' ':'
index e5dca5e..c22e08a 100644 (file)
@@ -1,5 +1,5 @@
 %{
-/*     $OpenBSD: scanner.l,v 1.9 2008/04/11 20:45:52 stefan Exp $   */
+/*     $OpenBSD: scanner.l,v 1.10 2008/08/17 18:40:13 ragge Exp $   */
 
 /*
  * Copyright (c) 2004 Anders Magnusson. All rights reserved.
@@ -40,7 +40,7 @@
 
 %{
 static void cvtdig(int rad);
-static int charcon(void);
+static int charcon(usch *);
 static void elsestmt(void);
 static void ifdefstmt(void);
 static void ifndefstmt(void);
@@ -83,15 +83,17 @@ yyinput(char *b, int m)
 }
 #undef YY_INPUT
 #undef YY_BUF_SIZE
-#define        YY_BUF_SIZE 32768
+#define        YY_BUF_SIZE (8*65536)
 #define YY_INPUT(b,r,m) (r = yyinput(b, m))
+#ifdef HAVE_CPP_VARARG_MACRO_GCC
 #define fprintf(x, ...) error(__VA_ARGS__)
+#endif
 #define        ECHO putstr((usch *)yytext)
 #undef fileno
 #define fileno(x) 0
 
 #if YY_FLEX_SUBMINOR_VERSION >= 31
-/* Hack to avoid unneccessary warnings */
+/* Hack to avoid unnecessary warnings */
 FILE *yyget_in (void);
 FILE *yyget_out  (void);
 int yyget_leng (void);
@@ -122,7 +124,7 @@ FS  (f|F|l|L)
 IS     (u|U|l|L)*
 WS     [\t ]
 
-%s IFR CONTR DEF
+%s IFR CONTR DEF COMMENT
 
 %%
 
@@ -177,7 +179,12 @@ WS [\t ]
                                return NUMBER;
                        }
 
-[1-9][0-9]*            { if (slow && !YYSTATE) return IDENT; scale = 10; goto num; }
+[0-9][0-9]*            {
+                               if (slow && !YYSTATE)
+                                       return IDENT;
+                               scale = yytext[0] == '0' ? 8 : 10;
+                               goto num;
+                       }
 
 0[xX]{H}+{IS}?         {       scale = 16;
                        num:    if (YYSTATE == IFR) 
@@ -186,11 +193,16 @@ WS        [\t ]
                        }
 0{D}+{IS}?             { scale = 8; goto num; }
 {D}+{IS}?              { scale = 10; goto num; }
-L?'(\\.|[^\\'])+'      {       if (YYSTATE) {
+'(\\.|[^\\'])+'                {
+                               if (YYSTATE || slow) {
                                        yylval.node.op = NUMBER;
-                                       yylval.node.nd_val = charcon();
+                                       yylval.node.nd_val = charcon((usch *)yytext);
+                                       return (NUMBER);
                                }
-                               PRTOUT(NUMBER);
+                               if (tflag)
+                                       yyless(1);
+                               if (!flslvl)
+                                       putstr((usch *)yytext);
                        }
 
 <IFR>.                 { return yytext[0]; }
@@ -225,13 +237,19 @@ L?'(\\.|[^\\'])+' {       if (YYSTATE) {
 
 
 "//".*$                        { /* if (tflag) yyless(..) */
-                               if (Cflag && !flslvl)
+                               if (Cflag && !flslvl && !slow)
                                        putstr((usch *)yytext);
                                else if (!flslvl)
                                        putch(' ');
                        }
 "/*"                   {       int c, wrn;
-                               if (Cflag && !flslvl)
+                               int prtcm = Cflag && !flslvl && !slow;
+                               extern int readmac;
+
+                               if (Cflag && !flslvl && readmac)
+                                       return CMNT;
+
+                               if (prtcm)
                                        putstr((usch *)yytext);
                                wrn = 0;
                        more:   while ((c = input()) && c != '*') {
@@ -239,20 +257,18 @@ L?'(\\.|[^\\'])+' {       if (YYSTATE) {
                                                putch(c), ifiles->lineno++;
                                        else if (c == 1) /* WARN */
                                                wrn = 1;
-                                       else if (Cflag && !flslvl)
+                                       else if (prtcm)
                                                putch(c);
                                }
                                if (c == 0)
                                        return 0;
-                               if (Cflag && !flslvl)
+                               if (prtcm)
                                        putch(c);
                                if ((c = input()) && c != '/') {
-                                       if (Cflag && !flslvl)
-                                               putch('*');
                                        unput(c);
                                        goto more;
                                }
-                               if (Cflag && !flslvl)
+                               if (prtcm)
                                        putch(c);
                                if (c == 0)
                                        return 0;
@@ -296,7 +312,22 @@ L?\"(\\.|[^\\"])*\"        { PRTOUT(STRING); }
                                xx: ;
                        }
 
-.                      { PRTOUT(yytext[0]); }
+.                      {
+                               if (YYSTATE || slow)
+                                       return yytext[0];
+                               if (yytext[0] == 6) { /* PRAGS */
+                                       usch *obp = stringbuf;
+                                       extern usch *prtprag(usch *);
+                                       *stringbuf++ = yytext[0];
+                                       do {
+                                               *stringbuf = input();
+                                       } while (*stringbuf++ != 14);
+                                       prtprag(obp);
+                                       stringbuf = obp;
+                               } else {
+                                       PRTOUT(yytext[0]);
+                               }
+                       }
 
 %%
 
@@ -424,12 +455,8 @@ pushfile(usch *file)
 
        slow = 0;
        if (file != NULL) {
-               if ((ic->infil = open((char *)file, O_RDONLY)) < 0) {
-                       if (errno != ENOENT)
-                               error("Cannot open '%s'. %s", file,
-                                               strerror(errno));
+               if ((ic->infil = open((char *)file, O_RDONLY)) < 0)
                        return -1;
-               }
                ic->orgfn = ic->fname = file;
                if (++inclevel > MAX_INCLEVEL)
                        error("Limit for nested includes exceeded");
@@ -480,7 +507,7 @@ prtline()
                        s = sheap("%s: %s\n", Mfile, ifiles->fname);
                        write(ofd, s, strlen((char *)s));
                }
-       } else
+       } else if (!Pflag)
                putstr(sheap("# %d \"%s\"\n", ifiles->lineno, ifiles->fname));
        stringbuf = os;
 }
@@ -490,7 +517,7 @@ cunput(int c)
 {
 #ifdef CPP_DEBUG
        extern int dflag;
-       if (dflag)printf(": '%c'(%d)", c, c);
+       if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c);
 #endif
        unput(c);
 }
@@ -544,14 +571,11 @@ cvtdig(int rad)
 }
 
 static int
-charcon(void)
+charcon(usch *p)
 {
-       usch *p = (usch *)yytext;
        int val, c;
 
-       if (*p == 'L')
-               p++;
-       p++; /* first ' */
+       p++; /* skip first ' */
        val = 0;
        if (*p++ == '\\') {
                switch (*p++) {
@@ -749,8 +773,20 @@ storepb(void)
        usch *opb = stringbuf;
        int c;
 
-       while ((c = input()) != '\n')
+       while ((c = input()) != '\n') {
+               if (c == '/') {
+                        if ((c = input()) == '*') {
+                               /* ignore comments here whatsoever */
+                               usch *g = stringbuf;
+                               getcmnt();
+                               stringbuf = g;
+                               continue;
+                       }
+                       unput(c);
+                       c = '/';
+               }
                savch(c);
+       }
        cunput('\n');
        savch(0);
        fixdefined(opb); /* XXX can fail if #line? */
@@ -876,3 +912,9 @@ badop(const char *op)
 {
        error("invalid operator in preprocessor expression: %s", op);
 }
+
+int
+cinput()
+{
+       return input();
+}
index 11f951f..249d041 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: code.c,v 1.8 2008/04/11 20:45:52 stefan Exp $ */
+/*     $OpenBSD: code.c,v 1.9 2008/08/17 18:40:13 ragge Exp $  */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -29,6 +29,8 @@
 
 # include "pass1.h"
 
+int lastloc = -1;
+
 /*
  * Define everything needed to print out some data (or text).
  * This means segment, alignment, visibility, etc.
@@ -37,8 +39,11 @@ void
 defloc(struct symtab *sp)
 {
        extern char *nextsect;
+#if defined(ELFABI) || defined(PECOFFABI)
        static char *loctbl[] = { "text", "data", "section .rodata" };
-       static int lastloc = -1;
+#elif defined(MACHOABI)
+       static char *loctbl[] = { "text", "data", "const_data" };
+#endif
        TWORD t;
        int s;
 
@@ -67,9 +72,13 @@ defloc(struct symtab *sp)
        if (t > UCHAR)
                printf("        .align %d\n", t > USHORT ? 4 : 2);
        if (sp->sclass == EXTDEF)
-               printf("        .globl %s\n", sp->soname);
+               printf("        .globl %s\n", exname(sp->soname));
+#if defined(ELFABI)
+       if (ISFTN(t))
+               printf("\t.type %s,@function\n", exname(sp->soname));
+#endif
        if (sp->slevel == 0)
-               printf("%s:\n", sp->soname);
+               printf("%s:\n", exname(sp->soname));
        else
                printf(LABFMT ":\n", sp->soffset);
 }
@@ -105,6 +114,10 @@ efcode()
 void
 bfcode(struct symtab **sp, int cnt)
 {
+#ifdef os_win32
+       extern int argstacksize;
+#endif
+       struct symtab *sp2;
        extern int gotnr;
        NODE *n, *p;
        int i;
@@ -114,6 +127,26 @@ bfcode(struct symtab **sp, int cnt)
                for (i = 0; i < cnt; i++) 
                        sp[i]->soffset += SZPOINT(INT);
        }
+
+#ifdef os_win32
+       /*
+        * Count the arguments and mangle name in symbol table as a callee.
+        */
+       argstacksize = 0;
+       if (cftnsp->sflags & SSTDCALL) {
+               char buf[64];
+               for (i = 0; i < cnt; i++) {
+                       TWORD t = sp[i]->stype;
+                       if (t == STRTY || t == UNIONTY)
+                               argstacksize += sp[i]->ssue->suesize;
+                       else
+                               argstacksize += szty(t) * SZINT / SZCHAR;
+               }
+               snprintf(buf, 64, "%s@%d", cftnsp->soname, argstacksize);
+               cftnsp->soname = newstring(buf, strlen(buf));
+       }
+#endif
+
        if (kflag) {
                /* Put ebx in temporary */
                n = block(REG, NIL, NIL, INT, 0, MKSUE(INT));
@@ -130,9 +163,9 @@ bfcode(struct symtab **sp, int cnt)
                if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY ||
                    cisreg(sp[i]->stype) == 0)
                        continue;
-               spname = sp[i];
+               sp2 = sp[i];
                n = tempnode(0, sp[i]->stype, sp[i]->sdf, sp[i]->ssue);
-               n = buildtree(ASSIGN, n, buildtree(NAME, 0, 0));
+               n = buildtree(ASSIGN, n, nametree(sp2));
                sp[i]->soffset = regno(n->n_left);
                sp[i]->sflags |= STNODE;
                ecomp(n);
@@ -149,16 +182,54 @@ bccode()
        SETOFF(autooff, SZINT);
 }
 
+#if defined(MACHOABI)
+struct stub stublist;
+struct stub nlplist;
+#endif
+
 /* called just before final exit */
 /* flag is 1 if errors, 0 if none */
 void
 ejobcode(int flag )
 {
+#if defined(MACHOABI)
+       /*
+        * iterate over the stublist and output the PIC stubs
+`       */
+       if (kflag) {
+               struct stub *p;
+
+               DLIST_FOREACH(p, &stublist, link) {
+                       printf("\t.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5\n");
+                       printf("L%s$stub:\n", p->name);
+                       printf("\t.indirect_symbol %s\n", exname(p->name));
+                       printf("\thlt ; hlt ; hlt ; hlt ; hlt\n");
+                       printf("\t.subsections_via_symbols\n");
+               }
+
+               printf("\t.section __IMPORT,__pointers,non_lazy_symbol_pointers\n");
+               DLIST_FOREACH(p, &nlplist, link) {
+                       printf("L%s$non_lazy_ptr:\n", p->name);
+                       printf("\t.indirect_symbol %s\n", exname(p->name));
+                       printf("\t.long 0\n");
+               }
+
+       }
+#endif
+
+#define _MKSTR(x) #x
+#define MKSTR(x) _MKSTR(x)
+#define OS MKSTR(TARGOS)
+        printf("\t.ident \"PCC: %s (%s)\"\n", PACKAGE_STRING, OS);
 }
 
 void
 bjobcode()
 {
+#if defined(MACHOABI)
+       DLIST_INIT(&stublist, link);
+       DLIST_INIT(&nlplist, link);
+#endif
 }
 
 /*
@@ -188,6 +259,7 @@ funcode(NODE *p)
        }
        if (kflag == 0)
                return p;
+#if defined(ELFABI)
        /* Create an ASSIGN node for ebx */
        l = block(REG, NIL, NIL, INT, 0, MKSUE(INT));
        l->n_rval = EBX;
@@ -199,6 +271,7 @@ funcode(NODE *p)
                        ;
                r->n_left = block(CM, l, r->n_left, INT, 0, MKSUE(INT));
        }
+#endif
        return p;
 }
 
index 9f3fe41..33e86e6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: local.c,v 1.7 2008/04/11 20:45:52 stefan Exp $        */
+/*     $OpenBSD: local.c,v 1.8 2008/08/17 18:40:13 ragge Exp $ */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -58,36 +58,69 @@ toolarge(TWORD t, CONSZ con)
        return 0;
 }
 
+#if defined(MACHOABI)
+
+/*
+ *  Keep track of PIC stubs.
+ */
+
+void
+addstub(struct stub *list, char *name)
+{
+        struct stub *s;
+
+        DLIST_FOREACH(s, list, link) {
+                if (strcmp(s->name, name) == 0)
+                        return;
+        }
+
+        s = permalloc(sizeof(struct stub));
+        s->name = permalloc(strlen(name) + 1);
+        strcpy(s->name, name);
+        DLIST_INSERT_BEFORE(list, s, link);
+}
+
+#endif
+
 #define        IALLOC(sz)      (isinlining ? permalloc(sz) : tmpalloc(sz))
+
+#ifndef os_win32
 /*
  * Make a symtab entry for PIC use.
  */
 static struct symtab *
-picsymtab(char *s, char *s2)
+picsymtab(char *p, char *s, char *s2)
 {
        struct symtab *sp = IALLOC(sizeof(struct symtab));
-       size_t len = strlen(s) + strlen(s2) + 1;
+       size_t len = strlen(p) + strlen(s) + strlen(s2) + 1;
        
        sp->sname = sp->soname = IALLOC(len);
-       strlcpy(sp->soname, s, len);
+       strlcpy(sp->soname, p, len);
+       strlcat(sp->soname, s, len);
        strlcat(sp->soname, s2, len);
        sp->sclass = EXTERN;
        sp->sflags = sp->slevel = 0;
        return sp;
 }
+#endif
 
 int gotnr; /* tempnum for GOT register */
+int argstacksize;
+
 /*
  * Create a reference for an extern variable.
  */
 static NODE *
 picext(NODE *p)
 {
+
+#if defined(ELFABI)
+
        NODE *q, *r;
        struct symtab *sp;
 
        q = tempnode(gotnr, PTR|VOID, 0, MKSUE(VOID));
-       sp = picsymtab(p->n_sp->soname, "@GOT");
+       sp = picsymtab("", p->n_sp->soname, "@GOT");
        r = xbcon(0, sp, INT);
        q = buildtree(PLUS, q, r);
        q = block(UMUL, q, 0, PTR|VOID, 0, MKSUE(VOID));
@@ -95,6 +128,38 @@ picext(NODE *p)
        q->n_sp = p->n_sp; /* for init */
        nfree(p);
        return q;
+
+#elif defined(MACHOABI)
+
+       NODE *q, *r;
+       struct symtab *sp;
+       char buf2[64];
+
+       if (p->n_sp->sclass == EXTDEF) {
+               snprintf(buf2, 64, "-L%s$pb", cftnsp->soname);
+               sp = picsymtab("", exname(p->n_sp->soname), buf2);
+       } else {
+               snprintf(buf2, 64, "$non_lazy_ptr-L%s$pb", cftnsp->soname);
+               sp = picsymtab("L", p->n_sp->soname, buf2);
+               addstub(&nlplist, p->n_sp->soname);
+       }
+       q = tempnode(gotnr, PTR+VOID, 0, MKSUE(VOID));
+       r = xbcon(0, sp, INT);
+       q = buildtree(PLUS, q, r);
+
+       if (p->n_sp->sclass != EXTDEF)
+               q = block(UMUL, q, 0, PTR+VOID, 0, MKSUE(VOID));
+       q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_sue);
+       q->n_sp = p->n_sp; /* for init */
+       nfree(p);
+       return q;
+
+#elif defined(PECOFFABI)
+
+       return p;
+
+#endif
+
 }
 
 /*
@@ -103,6 +168,9 @@ picext(NODE *p)
 static NODE *
 picstatic(NODE *p)
 {
+
+#if defined(ELFABI)
+
        NODE *q, *r;
        struct symtab *sp;
 
@@ -110,9 +178,9 @@ picstatic(NODE *p)
        if (p->n_sp->slevel > 0 || p->n_sp->sclass == ILABEL) {
                char buf[32];
                snprintf(buf, 32, LABFMT, (int)p->n_sp->soffset);
-               sp = picsymtab(buf, "@GOTOFF");
+               sp = picsymtab("", buf, "@GOTOFF");
        } else
-               sp = picsymtab(p->n_sp->soname, "@GOTOFF");
+               sp = picsymtab("", p->n_sp->soname, "@GOTOFF");
        sp->sclass = STATIC;
        sp->stype = p->n_sp->stype;
        r = xbcon(0, sp, INT);
@@ -121,6 +189,39 @@ picstatic(NODE *p)
        q->n_sp = p->n_sp; /* for init */
        nfree(p);
        return q;
+
+#elif defined(MACHOABI)
+
+       NODE *q, *r;
+       struct symtab *sp;
+       char buf2[64];
+
+       snprintf(buf2, 64, "-L%s$pb", cftnsp->soname);
+
+       if (p->n_sp->slevel > 0 || p->n_sp->sclass == ILABEL) {
+               char buf1[64];
+               snprintf(buf1, 64, LABFMT, (int)p->n_sp->soffset);
+               sp = picsymtab("", buf1, buf2);
+               sp->sflags |= SNOUNDERSCORE;
+       } else  {
+               sp = picsymtab("", exname(p->n_sp->soname), buf2);
+       }
+       sp->sclass = STATIC;
+       sp->stype = p->n_sp->stype;
+       q = tempnode(gotnr, PTR+VOID, 0, MKSUE(VOID));
+       r = xbcon(0, sp, INT);
+       q = buildtree(PLUS, q, r);
+       q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_sue);
+       q->n_sp = p->n_sp;
+       nfree(p);
+       return q;
+
+#elif defined(PECOFFABI)
+
+       return p;
+
+#endif
+
 }
 
 #ifdef TLS
@@ -131,7 +232,7 @@ static NODE *
 tlspic(NODE *p)
 {
        NODE *q, *r;
-       struct symtab *sp;
+       struct symtab *sp, *sp2;
 
        /*
         * creates:
@@ -141,7 +242,7 @@ tlspic(NODE *p)
 
        /* calc address of var@TLSGD */
        q = tempnode(gotnr, PTR|VOID, 0, MKSUE(VOID));
-       sp = picsymtab(p->n_sp->soname, "@TLSGD");
+       sp = picsymtab("", p->n_sp->soname, "@TLSGD");
        r = xbcon(0, sp, INT);
        q = buildtree(PLUS, q, r);
 
@@ -151,9 +252,9 @@ tlspic(NODE *p)
        q = buildtree(ASSIGN, r, q);
 
        /* call ___tls_get_addr */
-       spname = lookup("___tls_get_addr@PLT", 0);
-       spname->stype = EXTERN|INT|FTN;
-       r = buildtree(NAME, NIL, NIL);
+       sp2 = lookup("___tls_get_addr@PLT", 0);
+       sp2->stype = EXTERN|INT|FTN;
+       r = nametree(sp2);
        r = buildtree(ADDROF, r, NIL);
        r = block(UCALL, r, NIL, INT, 0, MKSUE(INT));
 
@@ -170,17 +271,18 @@ static NODE *
 tlsnonpic(NODE *p)
 {
        NODE *q, *r;
-       struct symtab *sp;
+       struct symtab *sp, *sp2;
        int ext = p->n_sp->sclass;
 
-       sp = picsymtab(p->n_sp->soname, ext == EXTERN ? "@INDNTPOFF" : "@NTPOFF");
+       sp = picsymtab("", p->n_sp->soname,
+           ext == EXTERN ? "@INDNTPOFF" : "@NTPOFF");
        q = xbcon(0, sp, INT);
        if (ext == EXTERN)
                q = block(UMUL, q, NIL, PTR|VOID, 0, MKSUE(VOID));
 
-       spname = lookup("%gs:0", 0);
-       spname->stype = EXTERN|INT;
-       r = buildtree(NAME, NIL, NIL);
+       sp2 = lookup("%gs:0", 0);
+       sp2->stype = EXTERN|INT;
+       r = nametree(sp2);
 
        q = buildtree(PLUS, q, r);
        q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_sue);
@@ -312,19 +414,21 @@ clocal(NODE *p)
        case USTCALL:
                if (kflag == 0)
                        break;
+#if defined(ELFABI)
                /* Change to CALL node with ebx as argument */
                l = block(REG, NIL, NIL, INT, 0, MKSUE(INT));
                l->n_rval = EBX;
                p->n_right = buildtree(ASSIGN, l,
                    tempnode(gotnr, INT, 0, MKSUE(INT)));
                p->n_op -= (UCALL-CALL);
+#endif
                break;
 
        case CBRANCH:
                l = p->n_left;
 
                /*
-                * Remove unneccessary conversion ops.
+                * Remove unnecessary conversion ops.
                 */
                if (clogop(l->n_op) && l->n_left->n_op == SCONV) {
                        if (coptype(l->n_op) != BITYPE)
@@ -520,8 +624,6 @@ clocal(NODE *p)
        case RS:
                /* shift count must be in a char
                 * unless longlong, where it must be int */
-               if (p->n_right->n_op == ICON)
-                       break; /* do not do anything */
                if (p->n_type == LONGLONG || p->n_type == ULONGLONG) {
                        if (p->n_right->n_type != INT)
                                p->n_right = block(SCONV, p->n_right, NIL,
@@ -549,6 +651,8 @@ clocal(NODE *p)
 static void
 fixnames(NODE *p)
 {
+#if !defined(PECOFFABI)
+
        struct symtab *sp;
        struct suedef *sue;
        NODE *q;
@@ -562,6 +666,7 @@ fixnames(NODE *p)
        sue = q->n_sue;
        if (q->n_op == UMUL)
                q = q->n_left, isu = 1;
+
        if (q->n_op == PLUS && q->n_left->n_op == TEMP &&
            q->n_right->n_op == ICON) {
                sp = q->n_right->n_sp;
@@ -575,12 +680,29 @@ fixnames(NODE *p)
                    sp->sclass != EXTDEF)
                        cerror("fixnames");
 
+#if defined(ELFABI)
+
                if ((c = strstr(sp->soname, "@GOT")) == NULL)
                        cerror("fixnames2");
                if (isu) {
                        memcpy(c, "@PLT", sizeof("@PLT"));
                } else
                        *c = 0;
+
+#elif defined(MACHOABI)
+
+               if ((c = strstr(sp->soname, "$non_lazy_ptr")) == NULL &&
+                   (c = strstr(sp->soname, "-L")) == NULL)
+                               cerror("fixnames2");
+               if (isu) {
+                       *c = 0;
+                       addstub(&stublist, sp->soname+1);
+                       strcpy(c, "$stub");
+               } else 
+                       *c = 0;
+
+#endif
+
                nfree(q->n_left);
                q = q->n_right;
                if (isu)
@@ -589,6 +711,7 @@ fixnames(NODE *p)
                p->n_left = q;
                q->n_sue = sue;
        }
+#endif
 }
 
 void
@@ -611,6 +734,7 @@ myp2tree(NODE *p)
 
        sp = IALLOC(sizeof(struct symtab));
        sp->sclass = STATIC;
+       sp->ssue = MKSUE(p->n_type);
        sp->slevel = 1; /* fake numeric label */
        sp->soffset = getlab();
        sp->sflags = 0;
@@ -618,7 +742,7 @@ myp2tree(NODE *p)
        sp->squal = (CON >> TSHIFT);
 
        defloc(sp);
-       ninval(0, btdims[p->n_type].suesize, p);
+       ninval(0, sp->ssue->suesize, p);
 
        p->n_op = NAME;
        p->n_lval = 0;
@@ -711,10 +835,22 @@ spalloc(NODE *t, NODE *p, OFFSZ off)
 void
 instring(struct symtab *sp)
 {
-       char *s, *str;
+       char *s, *str = sp->sname;
+
+#if defined(ELFABI) || defined(PECOFFABI)
 
        defloc(sp);
-       str = sp->sname;
+
+#elif defined(MACHOABI)
+
+       extern int lastloc;
+       if (lastloc != STRNG)
+               printf("        .cstring\n");
+       lastloc = STRNG;
+       printf("\t.p2align 2\n");
+       printf(LABFMT ":\n", sp->soffset);
+
+#endif
 
        /* be kind to assemblers and avoid long strings */
        printf("\t.ascii \"");
@@ -742,7 +878,7 @@ inwstring(struct symtab *sp)
        NODE *p;
 
        defloc(sp);
-       p = bcon(0);
+       p = xbcon(0, NULL, WCHAR_TYPE);
        do {
                if (*s++ == '\\')
                        p->n_lval = esccon(&s);
@@ -821,7 +957,9 @@ ninval(CONSZ off, int fsz, NODE *p)
 {
        union { float f; double d; long double l; int i[3]; } u;
        struct symtab *q;
+#if defined(ELFABI) || defined(MACHOABI)
        char *c;
+#endif
        TWORD t;
        int i;
 
@@ -840,8 +978,22 @@ ninval(CONSZ off, int fsz, NODE *p)
                        p = p->n_left;
                p = p->n_right;
                q = p->n_sp;
+
+#if defined(ELFABI)
+
                if ((c = strstr(q->soname, "@GOT")) != NULL)
                        *c = 0; /* ignore GOT ref here */
+
+#elif defined(MACHOABI)
+
+               if  ((c = strstr(q->soname, "$non_lazy_ptr")) != NULL) {
+                       q->soname++;    /* skip "L" */
+                       *c = 0; /* ignore GOT ref here */
+               }
+               else if ((c = strstr(q->soname, "-L")) != NULL)
+                       *c = 0; /* ignore GOT ref here */
+
+#endif
        }
        if (p->n_op != ICON && p->n_op != FCON)
                cerror("ninval: init node not constant");
@@ -866,8 +1018,14 @@ ninval(CONSZ off, int fsz, NODE *p)
                        if ((q->sclass == STATIC && q->slevel > 0) ||
                            q->sclass == ILABEL) {
                                printf("+" LABFMT, q->soffset);
-                       } else
-                               printf("+%s", exname(q->soname));
+                       } else {
+#if defined(MACHOABI)
+                               if ((q->sflags & SNOUNDERSCORE) != 0)
+                                       printf("+%s", q->soname);
+                               else
+#endif
+                                       printf("+%s", exname(q->soname));
+                       }
                }
                printf("\n");
                break;
@@ -886,11 +1044,20 @@ ninval(CONSZ off, int fsz, NODE *p)
        case LDOUBLE:
                u.i[2] = 0;
                u.l = (long double)p->n_dcon;
+#if defined(HOST_BIG_ENDIAN)
+               /* XXX probably broken on most hosts */
+               printf("\t.long\t0x%x,0x%x,0x%x\n", u.i[2], u.i[1], u.i[0]);
+#else
                printf("\t.long\t0x%x,0x%x,0x%x\n", u.i[0], u.i[1], u.i[2]);
+#endif
                break;
        case DOUBLE:
                u.d = (double)p->n_dcon;
+#if defined(HOST_BIG_ENDIAN)
+               printf("\t.long\t0x%x,0x%x\n", u.i[1], u.i[0]);
+#else
                printf("\t.long\t0x%x,0x%x\n", u.i[0], u.i[1]);
+#endif
                break;
        case FLOAT:
                u.f = (float)p->n_dcon;
@@ -905,9 +1072,29 @@ ninval(CONSZ off, int fsz, NODE *p)
 char *
 exname(char *p)
 {
+#if defined(PECOFFABI) || defined(MACHOABI)
+
+#define NCHNAM  256
+       static char text[NCHNAM+1];
+       int i;
+
        if (p == NULL)
                return "";
-       return p;
+
+       text[0] = '_';
+       for (i=1; *p && i<NCHNAM; ++i)
+               text[i] = *p++;
+
+       text[i] = '\0';
+       text[NCHNAM] = '\0';  /* truncate */
+
+       return (text);
+
+#else
+
+       return (p == NULL ? "" : p);
+
+#endif
 }
 
 /*
@@ -962,12 +1149,40 @@ defzero(struct symtab *sp)
                printf(LABFMT ",0%o\n", sp->soffset, off);
 }
 
+static char *
+section2string(char *name, int len)
+{
+#if defined(ELFABI)
+       char *s;
+       int n;
+
+       if (strncmp(name, "link_set", 8) == 0) {
+               const char *postfix = ",\"aw\",@progbits";
+               n = len + strlen(postfix) + 1;
+               s = IALLOC(n);
+               strlcpy(s, name, n);
+               strlcat(s, postfix, n);
+               return s;
+       }
+#endif
+
+       return newstring(name, len);
+}
+
 char *nextsect;
 #ifdef TLS
 static int gottls;
 #endif
+#ifdef os_win32
+static int stdcall;
+static int dllindirect;
+#endif
+static char *alias;
+static int constructor;
+static int destructor;
 
-/* * Give target the opportunity of handling pragmas.
+/*
+ * Give target the opportunity of handling pragmas.
  */
 int
 mypragma(char **ary)
@@ -978,10 +1193,46 @@ mypragma(char **ary)
                return 1;
        }
 #endif
-       if (strcmp(ary[1], "section") || ary[2] == NULL)
-               return 0;
-       nextsect = newstring(ary[2], strlen(ary[2]));
-       return 1;
+#ifdef os_win32
+       if (strcmp(ary[1], "stdcall") == 0) {
+               stdcall = 1;
+               return 1;
+       }
+       if (strcmp(ary[1], "cdecl") == 0) {
+               stdcall = 0;
+               return 1;
+       }
+       if (strcmp(ary[1], "fastcall") == 0) {
+               stdcall = 2;
+               return 1;
+       }
+       if (strcmp(ary[1], "dllimport") == 0) {
+               dllindirect = 1;
+               return 1;
+       }
+       if (strcmp(ary[1], "dllexport") == 0) {
+               dllindirect = 1;
+               return 1;
+       }
+#endif
+       if (strcmp(ary[1], "constructor") == 0 || strcmp(ary[1], "init") == 0) {
+               constructor = 1;
+               return 1;
+       }
+       if (strcmp(ary[1], "destructor") == 0 || strcmp(ary[1], "fini") == 0) {
+               destructor = 1;
+               return 1;
+       }
+       if (strcmp(ary[1], "section") == 0 && ary[2] != NULL) {
+               nextsect = section2string(ary[2], strlen(ary[2]));
+               return 1;
+       }
+       if (strcmp(ary[1], "alias") == 0 && ary[2] != NULL) {
+               alias = tmpstrdup(ary[2]);
+               return 1;
+       }
+
+       return 0;
 }
 
 /*
@@ -995,5 +1246,165 @@ fixdef(struct symtab *sp)
        if (gottls)
                sp->sflags |= STLS;
        gottls = 0;
+#endif
+       if (alias != NULL && (sp->sclass != PARAM)) {
+               printf("\t.globl %s\n", exname(sp->soname));
+               printf("%s = ", exname(sp->soname));
+               printf("%s\n", exname(alias));
+               alias = NULL;
+       }
+       if ((constructor || destructor) && (sp->sclass != PARAM)) {
+#if defined(ELFABI)
+               printf("\t.section .%ctors,\"aw\",@progbits\n",
+                   constructor ? 'c' : 'd');
+#elif defined(MACHOABI)
+               if (kflag) {
+                       if (constructor)
+                               printf("\t.mod_init_func\n");
+                       else
+                               printf("\t.mod_term_func\n");
+               } else {
+                       if (constructor)
+                               printf("\t.constructor\n");
+                       else
+                               printf("\t.destructor\n");
+               }
+#endif
+               printf("\t.p2align 2\n");
+               printf("\t.long %s\n", exname(sp->sname));
+               constructor = destructor = 0;
+       }
+#ifdef os_win32
+       if (stdcall && (sp->sclass != PARAM)) {
+               sp->sflags |= SSTDCALL;
+               stdcall = 0;
+       }
+       if (dllindirect && (sp->sclass != PARAM)) {
+               sp->sflags |= SDLLINDIRECT;
+               dllindirect = 0;
+       }
+#endif
+}
+
+NODE *
+i386_builtin_return_address(NODE *f, NODE *a)
+{
+       int nframes;
+
+       if (a == NULL || a->n_op != ICON)
+               goto bad;
+
+       nframes = a->n_lval;
+
+       tfree(f);
+       tfree(a);
+
+       f = block(REG, NIL, NIL, PTR+VOID, 0, MKSUE(VOID));
+       regno(f) = FPREG;
+
+       while (nframes--)
+               f = block(UMUL, f, NIL, PTR+VOID, 0, MKSUE(VOID));
+
+       f = block(PLUS, f, bcon(4), INCREF(PTR+VOID), 0, MKSUE(VOID));
+       f = buildtree(UMUL, f, NIL);
+
+       return f;
+bad:
+        uerror("bad argument to __builtin_return_address");
+        return bcon(0);
+}
+
+NODE *
+i386_builtin_frame_address(NODE *f, NODE *a)
+{
+       int nframes;
+
+       if (a == NULL || a->n_op != ICON)
+               goto bad;
+
+       nframes = a->n_lval;
+
+       tfree(f);
+       tfree(a);
+
+       f = block(REG, NIL, NIL, PTR+VOID, 0, MKSUE(VOID));
+       regno(f) = FPREG;
+
+       while (nframes--)
+               f = block(UMUL, f, NIL, PTR+VOID, 0, MKSUE(VOID));
+
+       return f;
+bad:
+        uerror("bad argument to __builtin_frame_address");
+        return bcon(0);
+}
+
+#ifdef os_win32
+/*
+ *  Postfix external functions with the arguments size.
+ */
+static void
+mangle(NODE *p)
+{
+       NODE *l, *r;
+       TWORD t;
+       int size = 0;
+       char buf[64];
+
+       if ((p->n_op == NAME || p->n_op == ICON) && 
+           p->n_sp && (p->n_sp->sflags & SDLLINDIRECT) && p->n_name) {
+               snprintf(buf, 64, "__imp_%s", p->n_name);
+               p->n_name = IALLOC(strlen(buf) + 1);
+               strcpy(p->n_name, buf);
+               return;
+       }
+
+       if (p->n_op != CALL && p->n_op != STCALL &&
+           p->n_op != UCALL && p->n_op != USTCALL)
+               return;
+
+       l = p->n_left;
+       if (l->n_op == ADDROF)
+               l = l->n_left;
+       if (l->n_sp == NULL)
+               return;
+       if (l->n_sp->sflags & SSTDCALL) {
+               if (strchr(l->n_name, '@') == NULL) {
+                       if (p->n_op == CALL || p->n_op == STCALL) {
+                               for (r = p->n_right;    
+                                   r->n_op == CM; r = r->n_left) {
+                                       t = r->n_type;
+                                       if (t == STRTY || t == UNIONTY)
+                                               size += r->n_sue->suesize;
+                                       else
+                                               size += szty(t) * SZINT / SZCHAR;
+                               }
+                               t = r->n_type;
+                               if (t == STRTY || t == UNIONTY)
+                                       size += r->n_sue->suesize;
+                               else
+                                       size += szty(t) * SZINT / SZCHAR;
+                       }
+                       snprintf(buf, 64, "%s@%d", l->n_name, size);
+                       l->n_name = IALLOC(strlen(buf) + 1);
+                       strcpy(l->n_name, buf);
+               }
+
+               l->n_flags = FSTDCALL;
+       }
+}
+#endif
+
+void
+pass1_lastchance(struct interpass *ip)
+{
+#ifdef os_win32
+       if (ip->type == IP_EPILOG) {
+               struct interpass_prolog *ipp = (struct interpass_prolog *)ip;
+               ipp->ipp_argstacksize = argstacksize;
+       }
+
+       if (ip->type == IP_NODE)
+                walkf(ip->ip_node, mangle);
 #endif
 }
index 70015de..355e2c4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: local2.c,v 1.8 2008/04/11 20:45:52 stefan Exp $       */
+/*     $OpenBSD: local2.c,v 1.9 2008/08/17 18:40:13 ragge Exp $        */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
 # include <ctype.h>
 # include <string.h>
 
-void acon(NODE *p);
-int argsize(NODE *p);
+#if defined(PECOFFABI) || defined(MACHOABI)
+#define EXPREFIX       "_"
+#else
+#define EXPREFIX       ""
+#endif
+
 
 static int stkpos;
 
@@ -51,11 +55,16 @@ static TWORD ftype;
 static void
 prtprolog(struct interpass_prolog *ipp, int addto)
 {
+#if defined(ELFABI)
        static int lwnr;
+#endif
        int i, j;
 
        printf("        pushl %%ebp\n");
        printf("        movl %%esp,%%ebp\n");
+#if defined(MACHOABI)
+       printf("        subl $8,%%esp\n");      /* 16-byte stack alignment */
+#endif
        if (addto)
                printf("        subl $%d,%%esp\n", addto);
        for (i = ipp->ipp_regs, j = 0; i; i >>= 1, j++)
@@ -64,6 +73,9 @@ prtprolog(struct interpass_prolog *ipp, int addto)
                            rnames[j], regoff[j], rnames[FPREG]);
        if (kflag == 0)
                return;
+
+#if defined(ELFABI)
+
        /* if ebx are not saved to stack, it must be moved into another reg */
        /* check and emit the move before GOT stuff */
        if ((ipp->ipp_regs & (1 << EBX)) == 0) {
@@ -89,8 +101,15 @@ prtprolog(struct interpass_prolog *ipp, int addto)
        printf("        call .LW%d\n", ++lwnr);
        printf(".LW%d:\n", lwnr);
        printf("        popl %%ebx\n");
-       printf("        addl $_GLOBAL_OFFSET_TABLE_+[.-.LW%d], %%ebx\n",
-           lwnr);
+       printf("        addl $_GLOBAL_OFFSET_TABLE_+[.-.LW%d], %%ebx\n", lwnr);
+
+#elif defined(MACHOABI)
+
+       printf("\tcall L%s$pb\n", ipp->ipp_name);
+       printf("L%s$pb:\n", ipp->ipp_name);
+       printf("\tpopl %%ebx\n");
+
+#endif
 }
 
 /*
@@ -119,6 +138,7 @@ prologue(struct interpass_prolog *ipp)
        int addto;
 
        ftype = ipp->ipp_type;
+
 #ifdef LANG_F77
        if (ipp->ipp_vis)
                printf("        .globl %s\n", ipp->ipp_name);
@@ -130,6 +150,9 @@ prologue(struct interpass_prolog *ipp)
         * add to the stack.
         */
        addto = offcalc(ipp);
+#if defined(MACHOABI)
+       addto = (addto + 15) & ~15;     /* stack alignment */
+#endif
        prtprolog(ipp, addto);
 }
 
@@ -153,11 +176,25 @@ eoftn(struct interpass_prolog *ipp)
        if (ftype == STRTY || ftype == UNIONTY) {
                printf("        movl 8(%%ebp),%%eax\n");
                printf("        leave\n");
-               printf("        ret $4\n");
+#ifdef os_win32
+               printf("        ret $%d\n", 4 + ipp->ipp_argstacksize);
+#else
+               printf("        ret $%d\n", 4);
+#endif
        } else {
                printf("        leave\n");
-               printf("        ret\n");
+#ifdef os_win32
+               if (ipp->ipp_argstacksize)
+                       printf("        ret $%d\n", ipp->ipp_argstacksize);
+               else
+#endif
+                       printf("        ret\n");
        }
+
+#if defined(ELFABI)
+       printf("\t.size " EXPREFIX "%s,.-" EXPREFIX "%s\n", ipp->ipp_name,
+           ipp->ipp_name);
+#endif
 }
 
 /*
@@ -348,7 +385,12 @@ starg(NODE *p)
        expand(p, 0, "  pushl AL\n");
        expand(p, 0, "  leal 8(%esp),A1\n");
        expand(p, 0, "  pushl A1\n");
-       fprintf(fp, "   call memcpy\n");
+#if defined(MACHOABI)
+       fprintf(fp, "   call L%s$stub\n", EXPREFIX "memcpy");
+       addstub(&stublist, "memcpy");
+#else
+       fprintf(fp, "   call %s\n", EXPREFIX "memcpy");
+#endif
        fprintf(fp, "   addl $12,%%esp\n");
 }
 
@@ -456,6 +498,8 @@ zzzcode(NODE *p, int c)
                break;
 
        case 'C':  /* remove from stack after subroutine call */
+               if (p->n_left->n_flags & FSTDCALL)
+                       break;
                pr = p->n_qual;
                if (p->n_op == STCALL || p->n_op == USTCALL)
                        pr += 4;
@@ -521,7 +565,8 @@ zzzcode(NODE *p, int c)
                else if (p->n_op == RS) ch = "ashr";
                else if (p->n_op == LS) ch = "ashl";
                else ch = 0, comperr("ZO");
-               printf("\tcall __%sdi3\n\taddl $%d,%s\n", ch, pr, rnames[ESP]);
+               printf("\tcall " EXPREFIX "__%sdi3\n\taddl $%d,%s\n",
+                       ch, pr, rnames[ESP]);
                 break;
 
        case 'P': /* push hidden argument on stack */
@@ -538,7 +583,12 @@ zzzcode(NODE *p, int c)
                printf("\tpushl $%d\n", p->n_stsize);
                expand(p, INAREG, "\tpushl AR\n");
                expand(p, INAREG, "\tleal AL,%eax\n\tpushl %eax\n");
-               printf("\tcall memcpy\n");
+#if defined(MACHOABI)
+               printf("\tcall L%s$stub\n", EXPREFIX "memcpy");
+               addstub(&stublist, "memcpy");
+#else
+               printf("\tcall %s\n", EXPREFIX "memcpy");
+#endif
                printf("\taddl $12,%%esp\n");
                break;
 
@@ -1069,8 +1119,10 @@ lastcall(NODE *p)
        for (p = p->n_right; p->n_op == CM; p = p->n_left)
                size += argsiz(p->n_right);
        size += argsiz(p);
+#if defined(ELFABI)
        if (kflag)
                size -= 4;
+#endif
        op->n_qual = size; /* XXX */
 }
 
@@ -1115,3 +1167,122 @@ void
 mflags(char *str)
 {
 }
+
+/*
+ * Do something target-dependent for xasm arguments.
+ */
+int
+myxasm(struct interpass *ip, NODE *p)
+{
+       struct interpass *ip2;
+       NODE *in = 0, *ut = 0;
+       TWORD t;
+       char *w;
+       int reg;
+       int cw;
+
+       cw = xasmcode(p->n_name);
+       if (cw & (XASMASG|XASMINOUT))
+               ut = p->n_left;
+       if ((cw & XASMASG) == 0)
+               in = p->n_left;
+
+       switch (XASMVAL(cw)) {
+       case 'D': reg = EDI; break;
+       case 'S': reg = ESI; break;
+       case 'a': reg = EAX; break;
+       case 'b': reg = EBX; break;
+       case 'c': reg = ECX; break;
+       case 'd': reg = EDX; break;
+       case 't': reg = 0; break;
+       case 'u': reg = 1; break;
+       case 'A': reg = EAXEDX; break;
+       case 'q': /* XXX let it be CLASSA as for now */
+               p->n_name = tmpstrdup(p->n_name);
+               w = strchr(p->n_name, 'q');
+               *w = 'r';
+               return 0;
+       default:
+               return 0;
+       }
+       p->n_name = tmpstrdup(p->n_name);
+       for (w = p->n_name; *w; w++)
+               ;
+       w[-1] = 'r'; /* now reg */
+       t = p->n_left->n_type;
+       if (reg == EAXEDX) {
+               p->n_label = CLASSC;
+       } else {
+               p->n_label = CLASSA;
+               if (t == CHAR || t == UCHAR) {
+                       p->n_label = CLASSB;
+                       reg = reg * 2 + 8;
+               }
+       }
+       if (t == FLOAT || t == DOUBLE || t == LDOUBLE) {
+               p->n_label = CLASSD;
+               reg += 037;
+       }
+
+       if (in && ut)
+               in = tcopy(in);
+       p->n_left = mklnode(REG, 0, reg, t);
+       if (ut) {
+               ip2 = ipnode(mkbinode(ASSIGN, ut, tcopy(p->n_left), t));
+               DLIST_INSERT_AFTER(ip, ip2, qelem);
+       }
+       if (in) {
+               ip2 = ipnode(mkbinode(ASSIGN, tcopy(p->n_left), in, t));
+               DLIST_INSERT_BEFORE(ip, ip2, qelem);
+       }
+       return 1;
+}
+
+void
+targarg(char *w, void *arg)
+{
+       NODE **ary = arg;
+       NODE *p, *q;
+
+       p = ary[(int)w[1]-'0']->n_left;
+       if (optype(p->n_op) != LTYPE)
+               comperr("bad xarg op %d", p->n_op);
+       q = tcopy(p);
+       if (q->n_op == REG) {
+               if (*w == 'k') {
+                       q->n_type = INT;
+               } else if (*w != 'w') {
+                       if (q->n_type > UCHAR) {
+                               regno(q) = regno(q)*2+8;
+                               if (*w == 'h')
+                                       regno(q)++;
+                       }
+                       q->n_type = INT;
+               } else
+                       q->n_type = SHORT;
+       }
+       adrput(stdout, q);
+       tfree(q);
+}
+
+/*
+ * target-specific conversion of numeric arguments.
+ */
+int
+numconv(void *ip, void *p1, void *q1)
+{
+       NODE *p = p1, *q = q1;
+       int cw = xasmcode(q->n_name);
+
+       switch (XASMVAL(cw)) {
+       case 'a':
+       case 'b':
+       case 'c':
+       case 'd':
+               p->n_name = tmpcalloc(2);
+               p->n_name[0] = XASMVAL(cw);
+               return 1;
+       default:
+               return 0;
+       }
+}
index 0343b1f..4b5248a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: macdefs.h,v 1.4 2008/04/11 20:45:52 stefan Exp $      */
+/*     $OpenBSD: macdefs.h,v 1.5 2008/08/17 18:40:13 ragge Exp $       */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -90,7 +90,7 @@
 /* Default char is signed */
 #undef CHAR_UNSIGNED
 #define        BOOL_TYPE       CHAR    /* what used to store _Bool */
-#if os_mirbsd
+#if defined(os_mirbsd) || defined(os_win32)
 #define WCHAR_TYPE     USHORT  /* ISO 10646 16-bit Unicode */
 #else
 #define        WCHAR_TYPE      INT     /* what used to store wchar_t */
@@ -104,8 +104,13 @@ typedef    unsigned long long U_CONSZ;
 typedef long long OFFSZ;
 
 #define CONFMT "%lld"          /* format for printing constants */
+#if defined(ELFABI)
 #define LABFMT ".L%d"          /* format for printing labels */
 #define        STABLBL ".LL%d"         /* format for stab (debugging) labels */
+#else
+#define LABFMT "L%d"           /* format for printing labels */
+#define        STABLBL "LL%d"          /* format for stab (debugging) labels */
+#endif
 #ifdef LANG_F77
 #define BLANKCOMMON "_BLNK_"
 #define MSKIREG  (M(TYSHORT)|M(TYLONG))
@@ -116,6 +121,10 @@ typedef long long OFFSZ;
 #define ARGOFFSET 8
 #endif
 
+#ifdef MACHOABI
+#define STAB_LINE_ABSOLUTE     /* S_LINE fields use absolute addresses */
+#endif
+
 #define BACKAUTO               /* stack grows negatively for automatics */
 #define BACKTEMP               /* stack grows negatively for temporaries */
 
@@ -302,3 +311,51 @@ int COLORMAP(int c, int *r);
  */
 #define        SSECTION        SLOCAL1
 #define        STLS            SLOCAL2
+#define        SNOUNDERSCORE   SLOCAL3
+#define SSTDCALL       SLOCAL2 
+#define SDLLINDIRECT   SLOCAL3
+
+/*
+ * i386-specific node flags.
+ */
+#define FSTDCALL       0x01
+
+/*
+ * i386-specific interpass stuff.
+ */
+
+#define TARGET_IPP_MEMBERS                     \
+       int ipp_argstacksize;
+
+/*
+ * Extended assembler macros.
+ */
+void targarg(char *w, void *arg);
+#define        XASM_TARGARG(w, ary)    \
+       (w[1] == 'b' || w[1] == 'h' || w[1] == 'w' || w[1] == 'k' ? \
+       w++, targarg(w, ary), 1 : 0)
+int numconv(void *ip, void *p, void *q);
+#define        XASM_NUMCONV(ip, p, q)  numconv(ip, p, q)
+
+/*
+ * builtins.
+ */
+#define TARGET_BUILTINS                                                        \
+       { "__builtin_frame_address", i386_builtin_frame_address },      \
+       { "__builtin_return_address", i386_builtin_return_address },
+
+#define NODE struct node
+struct node;
+NODE *i386_builtin_frame_address(NODE *f, NODE *a);
+NODE *i386_builtin_return_address(NODE *f, NODE *a);
+#undef NODE
+
+#if defined(MACHOABI)
+struct stub {
+       struct { struct stub *q_forw, *q_back; } link;
+       char *name;
+};    
+extern struct stub stublist;
+extern struct stub nlplist;
+void addstub(struct stub *list, char *name);
+#endif
index 8370d12..ef95b63 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: table.c,v 1.6 2008/04/11 20:45:52 stefan Exp $        */
+/*     $OpenBSD: table.c,v 1.7 2008/08/17 18:40:13 ragge Exp $ */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -229,7 +229,7 @@ struct optab table[] = {
 
 /* convert int to char. This is done when register is loaded */
 { SCONV,       INCH,
-       SAREG,  TWORD,
+       SAREG,  TWORD|TPOINT,
        SANY,   TCHAR|TUCHAR,
                NSPECIAL|NBREG|NBSL,    RESC1,
                "ZM", },
@@ -976,7 +976,7 @@ struct optab table[] = {
        SNAME|SOREG,    TLDOUBLE,
        SHFL,   TFLOAT|TDOUBLE|TLDOUBLE,
                0,      RDEST,
-               "       fstt AL\n", },
+               "       fst AL\n", },
 
 { ASSIGN,      FOREFF,
        SNAME|SOREG,    TLDOUBLE,
@@ -1316,7 +1316,7 @@ struct optab table[] = {
                0,      RNOP,
                "       jmp LL\n", },
 
-#ifdef GCC_COMPAT
+#if defined(GCC_COMPAT) || defined(LANG_F77)
 { GOTO,        FOREFF,
        SAREG,  TANY,
        SANY,   TANY,
index 95ee535..99635d5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: common.c,v 1.9 2008/04/11 20:45:52 stefan Exp $       */
+/*     $OpenBSD: common.c,v 1.10 2008/08/17 18:40:13 ragge Exp $       */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -152,6 +152,7 @@ werror(char *s, ...)
 static NODE *freelink;
 static int usednodes;
 
+#ifndef LANG_F77
 NODE *
 talloc()
 {
@@ -178,6 +179,7 @@ talloc()
                printf("alloc node %p from memory\n", p);
        return p;
 }
+#endif
 
 /*
  * make a fresh copy of p
@@ -200,6 +202,7 @@ tcopy(NODE *p)
        return(q);
 }
 
+#ifndef LANG_F77
 /*
  * ensure that all nodes have been freed
  */
@@ -214,6 +217,7 @@ tcheck()
        if ((usednodes - inlnodecnt) != 0)
                cerror("usednodes == %d, inlnodecnt %d", usednodes, inlnodecnt);
 }
+#endif
 
 /*
  * free the tree p
@@ -232,7 +236,9 @@ tfree(NODE *p)
 NODE *
 nfree(NODE *p)
 {
+#ifndef LANG_F77
        extern int inlnodecnt, recovernodes;
+#endif
        NODE *l;
 #ifdef PCC_DEBUG_NODES
        NODE *q;
@@ -259,12 +265,20 @@ nfree(NODE *p)
        p->next = freelink;
        freelink = p;
        usednodes--;
+#ifndef LANG_F77
        if (recovernodes)
                inlnodecnt--;
+#endif
        return l;
 }
 #endif
 
+#ifdef LANG_F77
+#define OPTYPE(x) optype(x)
+#else
+#define OPTYPE(x) coptype(x)
+#endif
+
 #ifdef MKEXT
 #define coptype(o)     (dope[o]&TYFLG)
 #else
@@ -283,7 +297,7 @@ fwalk(NODE *t, void (*f)(NODE *, int, int *, int *), int down)
 
        (*f)(t, down, &down1, &down2);
 
-       switch (coptype( t->n_op )) {
+       switch (OPTYPE( t->n_op )) {
 
        case BITYPE:
                fwalk( t->n_left, f, down1 );
@@ -304,7 +318,8 @@ walkf(NODE *t, void (*f)(NODE *))
 {
        int opty;
 
-       opty = coptype(t->n_op);
+
+       opty = OPTYPE(t->n_op);
 
        if (opty != LTYPE)
                walkf( t->n_left, f );
@@ -419,6 +434,9 @@ tprint(FILE *fp, TWORD t, TWORD q)
                "void",
                "signed", /* pass1 */
                "bool", /* pass1 */
+               "fcomplex", /* pass1 */
+               "dcomplex", /* pass1 */
+               "lcomplex", /* pass1 */
                "?", "?"
                };
 
@@ -600,6 +618,18 @@ tmpvsprintf(char *fmt, va_list ap)
        return tmp;
 }
 
+/*
+ * Duplicate a string onto the temporary heap.
+ */
+char *
+tmpstrdup(char *str)
+{
+       int len;
+
+       len = strlen(str) + 1;
+       return memcpy(tmpalloc(len), str, len);
+}
+
 void
 tmpfree()
 {
@@ -644,3 +674,48 @@ newstring(char *s, int len)
                *c++ = *s++;
        return u;
 }
+
+/*
+ * Do a preorder walk of the CM list p and apply function f on each element.
+ */
+void
+flist(NODE *p, void (*f)(NODE *, void *), void *arg)
+{
+       if (p->n_op == CM) {
+               (*f)(p->n_right, arg);
+               flist(p->n_left, f, arg);
+       } else
+               (*f)(p, arg);
+}
+
+/*
+ * The same as flist but postorder.
+ */
+void
+listf(NODE *p, void (*f)(NODE *))
+{
+       if (p->n_op == CM) {
+               listf(p->n_left, f);
+               (*f)(p->n_right);
+       } else
+               (*f)(p);
+}
+
+/*
+ * Get list argument number n from list, or NIL if out of list.
+ */
+NODE *
+listarg(NODE *p, int n, int *cnt)
+{
+       NODE *r;
+
+       if (p->n_op == CM) {
+               r = listarg(p->n_left, n, cnt);
+               if (n == ++(*cnt))
+                       r = p->n_right;
+       } else {
+               *cnt = 0;
+               r = n == 0 ? p : NIL;
+       }
+       return r;
+}
index a41278c..368face 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: manifest.h,v 1.10 2008/04/11 20:45:52 stefan Exp $    */
+/*     $OpenBSD: manifest.h,v 1.11 2008/08/17 18:40:13 ragge Exp $     */
 /*
  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
  *
@@ -180,7 +180,10 @@ extern int ddebug, xdebug, f2debug;
 extern int iTflag, oTflag, kflag;
 extern int sflag, nflag, gflag, pflag;
 extern int Wstrict_prototypes, Wmissing_prototypes, Wimplicit_int,
-       Wimplicit_function_declaration;
+       Wimplicit_function_declaration, Wpointer_sign, Wshadow,
+       Wsign_compare, Wunknown_pragmas, Wunreachable_code;
+extern int funsigned_char;
+extern int sspflag;
 extern int xssaflag, xtailcallflag, xtemps, xdeljumps;
 
 int yyparse(void);
@@ -263,6 +266,9 @@ struct interpass_prolog {
        int ipp_autos;          /* Size on stack needed */
        int ip_tmpnum;          /* # allocated temp nodes so far */
        int ip_lblnum;          /* # used labels so far */
+#ifdef TARGET_IPP_MEMBERS
+       TARGET_IPP_MEMBERS
+#endif
 };
 
 /*
@@ -302,6 +308,8 @@ void *tmpcalloc(int size);
 void *tmpalloc(int size);
 void tmpfree(void);
 char *newstring(char *, int len);
+char *tmpstrdup(char *str);
+
 
 /* command-line processing */
 void mflags(char *);
@@ -318,6 +326,10 @@ void pass2_compile(struct interpass *);
 NODE *nfree(NODE *);
 NODE *tcopy(NODE *);
 void fwalk(NODE *t, void (*f)(NODE *, int, int *, int *), int down);
+void flist(NODE *p, void (*f)(NODE *, void *), void *);
+void listf(NODE *p, void (*f)(NODE *));
+NODE *listarg(NODE *p, int n, int *cnt);
+
 
 extern int nerrors;            /* number of errors seen so far */
 extern int warniserr;          /* treat warnings as errors */
index 3204f42..6f14573 100644 (file)
@@ -1,4 +1,4 @@
-/*      $OpenBSD: match.c,v 1.9 2008/04/11 20:45:52 stefan Exp $   */
+/*      $OpenBSD: match.c,v 1.10 2008/08/17 18:40:13 ragge Exp $   */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-# include "pass2.h"
+#include "pass2.h"
 
+#ifdef HAVE_STRINGS_H
 #include <strings.h>
+#endif
 
-void prttype(int t);
 void setclass(int tmp, int class);
 int getclass(int tmp);
 
@@ -385,26 +386,6 @@ getlr(NODE *p, int c)
        return NULL;
 }
 
-static char *tarr[] = {
-       "CHAR", "SHORT", "INT", "LONG", "FLOAT", "DOUBLE", "POINT", "UCHAR",
-       "USHORT", "UINT", "ULONG", "PTRTO", "ANY", "STRUCT", "LONGLONG",
-       "ULONGLONG",
-};
-
-void
-prttype(int t)
-{
-       int i, gone = 0;
-
-       for (i = 0; i < 16; i++)
-               if ((t >> i) & 1) {
-                       if (gone) putchar('|');
-                       gone++;
-                       printf("%s", tarr[i]);
-               }
-}
-
-
 #ifdef PCC_DEBUG
 #define        F2DEBUG(x)      if (f2debug) printf x
 #define        F2WALK(x)       if (f2debug) fwalk(x, e2print, 0)
index f0fcdbd..d06aa1b 100644 (file)
@@ -6,6 +6,8 @@
 
 #include <string.h>
 
+#define FMTdPTR "%td"
+
 int chkop[DSIZE];
 
 void mktables(void);
@@ -73,8 +75,22 @@ compl(struct optab *q, char *str)
        if (op < OPSIMP) {
                s = opst[op];
        } else
-               s = "Special op";
-       printf("table entry %td, op %s: %s\n", q - table, s, str);
+               switch (op) {
+               default:        s = "Special op";       break;
+               case OPSIMP:    s = "OPLSIMP";  break;
+               case OPCOMM:    s = "OPCOMM";   break;
+               case OPMUL:     s = "OPMUL";    break;
+               case OPDIV:     s = "OPDIV";    break;
+               case OPUNARY:   s = "OPUNARY";  break;
+               case OPLEAF:    s = "OPLEAF";   break;
+               case OPANY:     s = "OPANY";    break;
+               case OPLOG:     s = "OPLOG";    break;
+               case OPFLOAT:   s = "OPFLOAT";  break;
+               case OPSHFT:    s = "OPSHFT";   break;
+               case OPLTYPE:   s = "OPLTYPE";  break;
+               }
+
+       printf("table entry " FMTdPTR ", op %s: %s\n", q - table, s, str);
 }
 
 static int
@@ -174,7 +190,7 @@ main(int argc, char *argv[])
                if ((q->rewrite & (RESC1|RESC2|RESC3)) && 
                    !(q->needs & REWRITE)) {
                        if ((q->visit & getrcl(q)) == 0) {
-                               compl(q, "rwong RESCx class");
+                               compl(q, "wrong RESCx class");
                                rval++;
                        }
                }
@@ -272,7 +288,7 @@ main(int argc, char *argv[])
        if (breg > mx) mx = breg;
        if (creg > mx) mx = creg;
        if (dreg > mx) mx = dreg;
-       if (mx > (sizeof(int)*8)-1) {
+       if (mx > (int)(sizeof(int)*8)-1) {
                printf("too many regs in a class, use two classes instead\n");
                printf("%d > %zu\n", mx, (sizeof(int)*8)-1);
                rval++;
@@ -342,7 +358,7 @@ mktables()
                for (op = table; op->op != FREE; op++) {
                        if (op->op < OPSIMP) {
                                if (op->op == i) {
-                                       P((fc, "%td, ", op - table));
+                                       P((fc, FMTdPTR ", ", op - table));
                                        curalen++;
                                }
                        } else {
@@ -350,11 +366,12 @@ mktables()
                                if ((opmtemp=mamask[op->op - OPSIMP])&SPFLG) {
                                        if (i==NAME || i==ICON || i==TEMP ||
                                            i==OREG || i == REG || i == FCON) {
-                                               P((fc, "%td, ", op - table));
+                                               P((fc, FMTdPTR ", ",
+                                                   op - table));
                                                curalen++;
                                        }
                                } else if ((dope[i]&(opmtemp|ASGFLG))==opmtemp){
-                                       P((fc, "%td, ", op - table));
+                                       P((fc, FMTdPTR ", ", op - table));
                                        curalen++;
                                }
                        }
index ba7ce53..c02737e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: node.h,v 1.3 2008/04/11 20:45:52 stefan Exp $ */
+/*     $OpenBSD: node.h,v 1.4 2008/08/17 18:40:13 ragge Exp $  */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -63,6 +63,7 @@ typedef struct node {
        union {
                int     _label;
                int     _stalign;
+               int     _flags;
                struct  suedef *_sue;
        } n_6;
        union {
@@ -90,6 +91,7 @@ typedef struct node {
 
 #define        n_label n_6._label
 #define        n_stalign n_6._stalign
+#define        n_flags n_6._flags
 #define        n_sue   n_6._sue
 
 #define        n_left  n_f.n_u.n_l._left
@@ -100,6 +102,9 @@ typedef struct node {
 #define        n_sp    n_f.n_u.n_r._sp
 #define        n_dcon  n_f._dcon
 
+#define        NLOCAL1 010000
+#define        NLOCAL2 020000
+#define        NLOCAL3 040000
 /*
  * Node types.
  *
index 393cbbd..4164ced 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: optim2.c,v 1.7 2008/01/12 17:17:28 ragge Exp $        */
+/*     $OpenBSD: optim2.c,v 1.8 2008/08/17 18:40:13 ragge Exp $        */
 /*
  * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -167,7 +167,6 @@ cvtaddrof(NODE *p)
                l->n_op = REG;
                l->n_lval = 0;
                l->n_rval = FPREG;
-               
        }
 }
 
@@ -430,7 +429,7 @@ again:      gotone = 0;
                        continue;
                ip->ip_node->n_right->n_lval = j;
                i = ip->ip_node->n_left->n_op;
-               if (i < EQ || i - EQ >= negrelsize)
+               if (i < EQ || i - EQ >= (int)negrelsize)
                        comperr("deljumps: unexpected op");
                ip->ip_node->n_left->n_op = negrel[i - EQ];
                tfree(n->ip_node);
@@ -473,7 +472,9 @@ optdump(struct interpass *ip)
        printf("type %s\n", nm[ip->type-1]);
        switch (ip->type) {
        case IP_NODE:
+#ifdef PCC_DEBUG
                fwalk(ip->ip_node, e2print, 0);
+#endif
                break;
        case IP_DEFLAB:
                printf("label " LABFMT "\n", ip->ip_lbl);
@@ -967,7 +968,7 @@ printip(struct interpass *pole)
        static char *foo[] = {
           0, "NODE", "PROLOG", "STKOFF", "EPILOG", "DEFLAB", "DEFNAM", "ASM" };
        struct interpass *ip;
-       struct interpass_prolog *ipp, *epp;
+       struct interpass_prolog *ipplg, *epplg;
 
        DLIST_FOREACH(ip, pole, qelem) {
                if (ip->type > MAXIP)
@@ -976,20 +977,22 @@ printip(struct interpass *pole)
                        printf("%s (%p): ", foo[ip->type], ip);
                switch (ip->type) {
                case IP_NODE: printf("\n");
+#ifdef PCC_DEBUG
                        fwalk(ip->ip_node, e2print, 0); break;
+#endif
                case IP_PROLOG:
-                       ipp = (struct interpass_prolog *)ip;
+                       ipplg = (struct interpass_prolog *)ip;
                        printf("%s %s regs %x autos %d mintemp %d minlbl %d\n",
-                           ipp->ipp_name, ipp->ipp_vis ? "(local)" : "",
-                           ipp->ipp_regs, ipp->ipp_autos, ipp->ip_tmpnum,
-                           ipp->ip_lblnum);
+                           ipplg->ipp_name, ipplg->ipp_vis ? "(local)" : "",
+                           ipplg->ipp_regs, ipplg->ipp_autos, ipplg->ip_tmpnum,
+                           ipplg->ip_lblnum);
                        break;
                case IP_EPILOG:
-                       epp = (struct interpass_prolog *)ip;
+                       epplg = (struct interpass_prolog *)ip;
                        printf("%s %s regs %x autos %d mintemp %d minlbl %d\n",
-                           epp->ipp_name, epp->ipp_vis ? "(local)" : "",
-                           epp->ipp_regs, epp->ipp_autos, epp->ip_tmpnum,
-                           epp->ip_lblnum);
+                           epplg->ipp_name, epplg->ipp_vis ? "(local)" : "",
+                           epplg->ipp_regs, epplg->ipp_autos, epplg->ip_tmpnum,
+                           epplg->ip_lblnum);
                        break;
                case IP_DEFLAB: printf(LABFMT "\n", ip->ip_lbl); break;
                case IP_DEFNAM: printf("\n"); break;
index 4b0c3b2..90082a2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pass2.h,v 1.8 2008/04/11 20:45:52 stefan Exp $        */
+/*     $OpenBSD: pass2.h,v 1.9 2008/08/17 18:40:13 ragge Exp $ */
 /*
  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
  *
@@ -267,6 +267,13 @@ void myormake(NODE *);
 int *livecall(NODE *);
 void prtreg(FILE *, NODE *);
 char *prcook(int);
+int myxasm(struct interpass *ip, NODE *p);
+int xasmcode(char *s);
+int freetemp(int k);
+int rewfld(NODE *p);
+void canon(NODE *);
+void mycanon(NODE *);
+void oreg2(NODE *p);
 
 void conput(FILE *, NODE *);
 
@@ -284,6 +291,15 @@ extern int regK[];
 #define        CLASSD  4
 #define        CLASSE  5
 
+/* used when parsing xasm codes */
+#define        XASMVAL(x)      ((x) & 0377)    /* get val from codeword */
+#define        XASMASG         0x100   /* = */
+#define        XASMCONSTR      0x200   /* & */
+#define        XASMINOUT       0x400   /* + */
+#define XASMALL                (XASMASG|XASMCONSTR|XASMINOUT)
+#define        XASMISINP(cw)   (((cw) & XASMASG) == 0)         /* input operand */
+#define        XASMISOUT(cw)   ((cw) & (XASMASG|XASMINOUT))    /* output operand */
+
 /* routines to handle double indirection */
 #ifdef R2REGS
 void makeor2(NODE *p, NODE *q, int, int);
@@ -383,12 +399,12 @@ struct basicblock {
 
 struct labelinfo {
        struct basicblock **arr;
-       unsigned int size;
+       int size;
        unsigned int low;
 };
 
 struct bblockinfo {
-       unsigned int size;
+       int size;
        struct basicblock **arr;
 };
 
index e266120..879c806 100644 (file)
@@ -1,8 +1,4 @@
-/*     $OpenBSD: protos.h,v 1.7 2008/01/12 17:17:28 ragge Exp $        */
-
-struct optab;
-struct symtab;
-struct sw;
+/*     $OpenBSD: protos.h,v 1.8 2008/08/17 18:40:13 ragge Exp $        */
 
 void cerror(char *s, ...);
 void werror(char *s, ...);
@@ -13,7 +9,6 @@ void tfree(NODE *);
 int tshape(NODE *, int);
 void tcheck(void);
 void mkdope(void);
-int tshape(NODE *p, int shape);
 int shtemp(NODE *p);
 int flshape(NODE *p);
 int shumul(NODE *p);
@@ -38,22 +33,16 @@ int fldexpand(NODE *, int, char **);
 void ecomp(NODE *p);
 void bccode(void);
 int upoff(int size, int alignment, int *poff);
-void fldty(struct symtab *p);
 void nidcl(NODE *p, int class);
 int noinit(void);
 void eprint(NODE *, int, int *, int *);
 int uclass(int class);
-void mycanon(NODE *);
 void setregs(void);
-void canon(NODE *);
 int tlen(NODE *p);
 int setbin(NODE *);
-void oreg2(NODE *p);
 int notoff(TWORD, int, CONSZ, char *);
 int notlval(NODE *);
 void ecode(NODE *p);
 int yylex(void);
 void yyerror(char *s);
 void p2tree(NODE *p);
-int rewfld(NODE *p);
-int freetemp(int k);
index 6729299..fd192cc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: reader.c,v 1.14 2008/04/11 20:45:52 stefan Exp $      */
+/*     $OpenBSD: reader.c,v 1.15 2008/08/17 18:40:13 ragge Exp $       */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -90,7 +90,7 @@ static struct interpass prepole;
 
 void saveip(struct interpass *ip);
 void deltemp(NODE *p);
-void cvtemps(struct interpass *epil);
+static void cvtemps(struct interpass *ipole, int op, int off);
 NODE *store(NODE *);
 static void fixxasm(struct interpass *ip);
 
@@ -228,15 +228,17 @@ pass2_compile(struct interpass *ip)
                if (ip->type != IP_NODE)
                        continue;
                canon(ip->ip_node);
+#ifdef PCC_DEBUG
                walkf(ip->ip_node, cktree);
+#endif
                if ((ip->ip_node = deluseless(ip->ip_node)) == NULL) {
                        DLIST_REMOVE(ip, qelem);
                } else while (!DLIST_ISEMPTY(&prepole, qelem)) {
-                       struct interpass *ipp;
+                       struct interpass *tipp;
 
-                       ipp = DLIST_NEXT(&prepole, qelem);
-                       DLIST_REMOVE(ipp, qelem);
-                       DLIST_INSERT_BEFORE(ip, ipp, qelem);
+                       tipp = DLIST_NEXT(&prepole, qelem);
+                       DLIST_REMOVE(tipp, qelem);
+                       DLIST_INSERT_BEFORE(ip, tipp, qelem);
                }
        }
 
@@ -484,7 +486,7 @@ again:      switch (o = p->n_op) {
 
        case XARG:
                /* generate code for correct class here */
-               geninsn(p->n_left, 1 << p->n_label);
+//             geninsn(p->n_left, 1 << p->n_label);
                break;
 
        default:
@@ -544,7 +546,7 @@ ckmove(NODE *p, NODE *q)
  * Rewrite node to register after instruction emit.
  */
 static void
-rewrite(NODE *p, int rewrite, int cookie)
+rewrite(NODE *p, int dorewrite, int cookie)
 {
        NODE *l, *r;
        int o;
@@ -580,13 +582,17 @@ rewrite(NODE *p, int rewrite, int cookie)
                tfree(l);
        if (optype(o) == BITYPE)
                tfree(r);
-       if (rewrite == 0)
+       if (dorewrite == 0)
                return;
        CDEBUG(("rewrite: %p, reg %s\n", p,
            p->n_reg == -1? "<none>" : rnames[DECRA(p->n_reg, 0)]));
        p->n_rval = DECRA(p->n_reg, 0);
 }
 
+#ifndef XASM_TARGARG
+#define        XASM_TARGARG(x,y) 0
+#endif
+
 /*
  * printout extended assembler.
  */
@@ -597,26 +603,38 @@ genxasm(NODE *p)
        int n = 1, o = 0;
        char *w;
 
-       for (q = p->n_left; q->n_op == CM; q = q->n_left)
-               n++;
-       nary = tmpalloc(sizeof(NODE *)*n);
-       o = n;
-       for (q = p->n_left; q->n_op == CM; q = q->n_left) {
-               gencode(q->n_right->n_left, INREGS);
-               nary[--o] = q->n_right;
-       }
-       gencode(q->n_left, INREGS);
-       nary[--o] = q;
+       if (p->n_left->n_op != ICON || p->n_left->n_type != STRTY) {
+               for (q = p->n_left; q->n_op == CM; q = q->n_left)
+                       n++;
+               nary = tmpalloc(sizeof(NODE *)*n);
+               o = n;
+               for (q = p->n_left; q->n_op == CM; q = q->n_left) {
+                       gencode(q->n_right->n_left, INREGS);
+                       nary[--o] = q->n_right;
+               }
+               gencode(q->n_left, INREGS);
+               nary[--o] = q;
+       } else
+               nary = 0;
 
        w = p->n_name;
        putchar('\t');
        while (*w != 0) {
                if (*w == '%') {
-                       if (w[1] < '1' || w[1] > (n + '0'))
-                               uerror("bad xasm arg number");
+                       if (w[1] == '%')
+                               putchar('%');
+                       else if (XASM_TARGARG(w, nary))
+                               ; /* handled by target */
+                       else if (w[1] < '0' || w[1] > (n + '0'))
+                               uerror("bad xasm arg number %c", w[1]);
                        else
-                               adrput(stdout, nary[(int)w[1]-'1']->n_left);
+                               adrput(stdout, nary[(int)w[1]-'0']->n_left);
                        w++;
+               } else if (*w == '\\') { /* Always 3-digit octal */
+                       int num = *++w - '0';
+                       num = (num << 3) + *++w - '0';
+                       num = (num << 3) + *++w - '0';
+                       putchar(num);
                } else
                        putchar(*w);
                w++;
@@ -1080,8 +1098,10 @@ comperr(char *str, ...)
        va_end(ap);
        prfil = stderr;
 
+#ifdef PCC_DEBUG
        if (nodepole && nodepole->n_op != FREE)
                fwalk(nodepole, e2print, 0);
+#endif
        exit(1);
 }
 
@@ -1146,6 +1166,7 @@ mkbinode(int op, NODE *left, NODE *right, TWORD type)
        p->n_right = right;
        p->n_type = type;
        p->n_regw = NULL;
+       p->n_su = 0;
        return p;
 }
 
@@ -1161,6 +1182,7 @@ mkunode(int op, NODE *left, int rval, TWORD type)
        p->n_rval = rval;
        p->n_type = type;
        p->n_regw = NULL;
+       p->n_su = 0;
        return p;
 }
 
@@ -1187,67 +1209,220 @@ rspecial(struct optab *q, int what)
        return -1;
 }
 
+#ifndef XASM_NUMCONV
+#define        XASM_NUMCONV(x,y,z)     0
+#endif
+
+/*
+ * change numeric argument redirections to the correct node type after 
+ * cleaning up the other nodes.
+ * be careful about input operands that may have different value than output.
+ */
+static void
+delnums(NODE *p, void *arg)
+{
+       struct interpass *ip = arg, *ip2;
+       NODE *r = ip->ip_node->n_left;
+       NODE *q;
+       TWORD t;
+       int cnt;
+
+       if (p->n_name[0] < '0' || p->n_name[0] > '9')
+               return; /* not numeric */
+       if ((q = listarg(r, p->n_name[0] - '0', &cnt)) == NIL)
+               comperr("bad delnums");
+
+       /* target may have opinions whether to do this conversion */
+       if (XASM_NUMCONV(ip, p, q))
+               return;
+
+       /* Delete number by adding move-to/from-temp.  Later on */
+       /* the temps may be rewritten to other LTYPEs */
+       t = p->n_left->n_type;
+       r = mklnode(TEMP, 0, epp->ip_tmpnum++, t);
+
+       /* pre node */
+       ip2 = ipnode(mkbinode(ASSIGN, tcopy(r), p->n_left, t));
+       DLIST_INSERT_BEFORE(ip, ip2, qelem);
+
+       /* post node */
+       ip2 = ipnode(mkbinode(ASSIGN, q->n_left, tcopy(r), t));
+       DLIST_INSERT_AFTER(ip, ip2, qelem);
+
+       p->n_left = tcopy(r);
+       q->n_left = r;
+
+       p->n_name = tmpstrdup(q->n_name);
+       if (*p->n_name == '=')
+               p->n_name++;
+}
+
 /*
  * Ensure that a node is correct for the destination.
  */
 static void
-ltypify(struct interpass *ip, NODE *p)
+ltypify(NODE *p, void *arg)
 {
+       struct interpass *ip = arg;
        struct interpass *ip2;
        TWORD t = p->n_left->n_type;
        NODE *q, *r;
-       char *w;
-//     int asg = 0, and = 0;
+       int cw, ooff;
+       char *c;
 
-#ifdef notyet
+again:
        if (myxasm(ip, p))
                return; /* handled by target-specific code */
-#endif
-       w = p->n_name;
-//     if (*w == '=')
-//             w++, asg = 1;
-       switch (*w) {
+
+       cw = xasmcode(p->n_name);
+       switch (XASMVAL(cw)) {
+       case 'p':
+               /* pointer */
+               /* just make register of it */
+               p->n_name = tmpstrdup(p->n_name);
+               c = strchr(p->n_name, XASMVAL(cw)); /* cannot fail */
+               *c = 'r';
+               /* FALLTHROUGH */
+       case 'g':  /* general; any operand */
        case 'r': /* general reg */
                /* set register class */
                p->n_label = gclass(p->n_left->n_type);
-               if (optype(p->n_left->n_op) == LTYPE)
+               if (p->n_left->n_op == REG || p->n_left->n_op == TEMP)
+                       break;
+               q = p->n_left;
+               r = (cw & XASMINOUT ? tcopy(q) : q);
+               p->n_left = mklnode(TEMP, 0, epp->ip_tmpnum++, t);
+               if ((cw & XASMASG) == 0) {
+                       ip2 = ipnode(mkbinode(ASSIGN, tcopy(p->n_left), r, t));
+                       DLIST_INSERT_BEFORE(ip, ip2, qelem);
+               }
+               if (cw & (XASMASG|XASMINOUT)) {
+                       /* output parameter */
+                       ip2 = ipnode(mkbinode(ASSIGN, q, tcopy(p->n_left), t));
+                       DLIST_INSERT_AFTER(ip, ip2, qelem);
+               }
+               break;
+
+       case '0': case '1': case '2': case '3': case '4':
+       case '5': case '6': case '7': case '8': case '9':
+               break;
+
+       case 'm': /* memory operand */
+               /* store and reload value */
+               q = p->n_left;
+               if (optype(q->n_op) == LTYPE) {
+                       if (q->n_op == TEMP) {
+                               ooff = BITOOR(freetemp(szty(t)));
+                               cvtemps(ip, q->n_rval, ooff);
+                       } else if (q->n_op == REG)
+                               comperr("xasm m and reg");
+               } else if (q->n_op == UMUL && 
+                   (q->n_left->n_op != TEMP && q->n_left->n_op != REG)) {
+                       t = q->n_left->n_type;
+                       ooff = epp->ip_tmpnum++;
+                       ip2 = ipnode(mkbinode(ASSIGN,
+                           mklnode(TEMP, 0, ooff, t), q->n_left, t));
+                       q->n_left = mklnode(TEMP, 0, ooff, t);
+                       DLIST_INSERT_BEFORE(ip, ip2, qelem);
+               }
+               break;
+
+       case 'i': /* immediate constant */
+       case 'n': /* numeric constant */
+               if (p->n_left->n_op == ICON)
                        break;
-               q = mklnode(TEMP, 0, epp->ip_tmpnum++, t);
-               r = tcopy(q);
-               ip2 = ipnode(mkbinode(ASSIGN, q, p->n_left, t));
-               DLIST_INSERT_BEFORE(ip, ip2, qelem);
-               p->n_left = r;
+               p->n_name = tmpstrdup(p->n_name);
+               c = strchr(p->n_name, XASMVAL(cw)); /* cannot fail */
+               if (c[1]) {
+                       c[0] = c[1], c[1] = 0;
+                       goto again;
+               } else
+                       uerror("constant required");
                break;
+
        default:
                uerror("unsupported xasm option string '%s'", p->n_name);
        }
-                       
-
-//     fwalk(p, e2print, 0);
 }
 
 /* Extended assembler hacks */
 static void
-fixxasm(struct interpass *ipole)
+fixxasm(struct interpass *pole)
 {
        struct interpass *ip;
        NODE *p;
 
-       DLIST_FOREACH(ip, ipole, qelem) {
+       DLIST_FOREACH(ip, pole, qelem) {
                if (ip->type != IP_NODE || ip->ip_node->n_op != XASM)
                        continue;
-               /* Got an assembler node */
+               thisline = ip->lineno;
                p = ip->ip_node->n_left;
 
+               if (p->n_op == ICON && p->n_type == STRTY)
+                       continue;
+
+               /* replace numeric redirections with its underlying type */
+               flist(p, delnums, ip);
+
                /*
                 * Ensure that the arg nodes can be directly addressable
                 * We decide that everything shall be LTYPE here.
                 */
-               for (; p->n_op == CM; p = p->n_left)
-                       ltypify(ip, p->n_right);
-               ltypify(ip, p);
-               p = ip->ip_node->n_right;
-               if (p->n_op != ICON || p->n_type != STRTY)
-                       uerror("xasm constraints not supported");
+               flist(p, ltypify, ip);
        }
 }
+
+/*
+ * Extract codeword from xasm string */
+int
+xasmcode(char *s)
+{
+       int cw = 0;
+
+       while (*s) {
+               switch ((int)*s) {
+               case '=': cw |= XASMASG; break;
+               case '&': cw |= XASMCONSTR; break;
+               case '+': cw |= XASMINOUT; break;
+               default:
+                       if ((*s >= 'a' && *s <= 'z') ||
+                           (*s >= 'A' && *s <= 'Z') ||
+                           (*s >= '0' && *s <= '9')) {
+                               cw |= *s;
+                               return cw;
+                       }
+                       uerror("bad xasm constraint %c", *s);
+               }
+               s++;
+       }
+       return cw;
+}
+
+static int xasnum, xoffnum;
+
+static void
+xconv(NODE *p)
+{
+       if (p->n_op != TEMP || p->n_rval != xasnum)
+               return;
+       p->n_op = OREG;
+       p->n_rval = FPREG;
+       p->n_lval = xoffnum;
+}
+
+/*
+ * Convert nodes of type TEMP to op with lval off.
+ */
+static void
+cvtemps(struct interpass *ipl, int tnum, int off)
+{
+       struct interpass *ip;
+
+       xasnum = tnum;
+       xoffnum = off;
+
+       DLIST_FOREACH(ip, ipl, qelem)
+               if (ip->type == IP_NODE)
+                       walkf(ip->ip_node, xconv);
+       walkf(ipl->ip_node, xconv);
+}
index 55f605a..0528bb2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: regs.c,v 1.16 2008/04/11 20:45:52 stefan Exp $        */
+/*     $OpenBSD: regs.c,v 1.17 2008/08/17 18:40:13 ragge Exp $ */
 /*
  * Copyright (c) 2005 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -162,14 +162,18 @@ newblock(NODE *p)
        REGW *nb = &nblock[regno(p)];
        if (nb->link.q_forw == 0) {
                DLIST_INSERT_AFTER(&initial, nb, link);
+#ifdef PCC_DEBUG
                ASGNUM(nb) = regno(p);
                RDEBUG(("Adding longtime %d for tmp %d\n",
                    nb->nodnum, regno(p)));
+#endif
        }
        if (nb->r_class == 0)
                nb->r_class = gclass(p->n_type);
+#ifdef PCC_DEBUG
        RDEBUG(("newblock: p %p, node %d class %d\n",
            p, nb->nodnum, nb->r_class));
+#endif
        return nb;
 }
 
@@ -280,11 +284,18 @@ nsucomp(NODE *p)
                return need;
        }
 
+#ifdef PCC_DEBUG
 #define        ADCL(n, cl)     \
        for (i = 0; i < n; i++, w++) {  w->r_class = cl; \
                DLIST_INSERT_BEFORE(&initial, w, link);  SETNUM(w); \
                UDEBUG(("Adding " #n " %d\n", w->nodnum)); \
        }
+#else
+#define        ADCL(n, cl)     \
+       for (i = 0; i < n; i++, w++) {  w->r_class = cl; \
+               DLIST_INSERT_BEFORE(&initial, w, link);  SETNUM(w); \
+       }
+#endif
 
        UDEBUG(("node %p numregs %d\n", p, nxreg+1));
        w = p->n_regw = tmpalloc(sizeof(REGW) * (nxreg+1));
@@ -297,7 +308,9 @@ nsucomp(NODE *p)
        SETNUM(w);
        if (w->r_class)
                DLIST_INSERT_BEFORE(&initial, w, link);
+#ifdef PCC_DEBUG
        UDEBUG(("Adding short %d class %d\n", w->nodnum, w->r_class));
+#endif
        w++;
        ADCL(nareg, CLASSA);
        ADCL(nbreg, CLASSB);
@@ -391,7 +404,7 @@ ncnt(int needs)
        return i;
 }
 
-static inline REGW *
+static REGW *
 popwlist(REGW *l)
 {
        REGW *w = DLIST_NEXT(l, link);
@@ -408,7 +421,7 @@ static REGM coalescedMoves, constrainedMoves, frozenMoves,
        worklistMoves, activeMoves;
 enum { COAL, CONSTR, FROZEN, WLIST, ACTIVE };
 
-static inline REGM *
+static REGM *
 popmlist(REGM *l)
 {
        REGM *w = DLIST_NEXT(l, link);
@@ -426,7 +439,7 @@ popmlist(REGM *l)
  *
  * Bitfields are used for liveness.  Bit arrays are allocated on the
  * heap for the "live" variable and on the stack for the in, out, gen
- * and kill variables. Therefore, for a temp number, the bit number must
+ * and killed variables. Therefore, for a temp number, the bit number must
  * be biased with tempmin.
  *
  * There may be an idea to use a different data structure to store 
@@ -497,7 +510,9 @@ LIVEDELR(REGW *x)
 {
        struct lives *l;
 
+#ifdef PCC_DEBUG
        RDEBUG(("LIVEDELR: %d\n", x->nodnum));
+#endif
        DLIST_FOREACH(l, &lused, link) {
                if (l->var != x)
                        continue;
@@ -594,9 +609,9 @@ AddEdge(REGW *u, REGW *v)
 {
        ADJL *x;
 
+#ifdef PCC_DEBUG
        RRDEBUG(("AddEdge: u %d v %d\n", ASGNUM(u), ASGNUM(v)));
 
-#ifdef PCC_DEBUG
 #if 0
        if (ASGNUM(u) == 0)
                comperr("AddEdge 0");
@@ -698,7 +713,9 @@ addalledges(REGW *e)
        int i, j, k;
        struct lives *l;
 
+#ifdef PCC_DEBUG
        RDEBUG(("addalledges for %d\n", e->nodnum));
+#endif
 
        if (e->r_class == -1)
                return; /* unused */
@@ -727,7 +744,9 @@ addalledges(REGW *e)
        /* short-lived temps */
        RDEBUG(("addalledges shortlived "));
        DLIST_FOREACH(l, &lused, link) {
+#ifdef PCC_DEBUG
                RRDEBUG(("%d ", ASGNUM(l->var)));
+#endif
                AddEdge(l->var, e);
        }
        RDEBUG(("done\n"));
@@ -743,7 +762,9 @@ moveadd(REGW *def, REGW *use)
 
        if (def == use)
                return; /* no move to itself XXX - ``shouldn't happen'' */
+#ifdef PCC_DEBUG
        RDEBUG(("moveadd: def %d use %d\n", ASGNUM(def), ASGNUM(use)));
+#endif
 
        r = WORKLISTMOVEADD(use, def);
        MOVELISTADD(def, r);
@@ -817,6 +838,50 @@ addedge_r(NODE *p, REGW *w)
                addedge_r(p->n_left, w);
 }
 
+/*
+ * add/del parameter from live set.
+ */
+static void
+setxarg(NODE *p)
+{
+       int i, ut = 0, in = 0;
+       int cw;
+
+       if (p->n_op == ICON && p->n_type == STRTY)
+               return;
+
+       RDEBUG(("setxarg %p %s\n", p, p->n_name));
+       cw = xasmcode(p->n_name);
+       if (XASMISINP(cw))
+               in = 1;
+       if (XASMISOUT(cw))
+               ut = 1;
+
+       switch (XASMVAL(cw)) {
+       case 'g':
+               if (p->n_left->n_op != REG && p->n_left->n_op != TEMP)
+                       break;
+               /* FALLTHROUGH */
+       case 'r':
+               i = regno(p->n_left);
+               if (ut) {
+                       REGW *rw = p->n_left->n_op == REG ? ablock : nblock;
+                       LIVEDEL(i);
+                       addalledges(&rw[i]);
+               }
+               if (in) {
+                       LIVEADD(i);
+               }
+               break;
+       case 'i':
+       case 'm':
+       case 'n':
+               break;
+       default:
+               comperr("bad ixarg %s", p->n_name);
+       }
+}
+
 /*
  * Do the in-tree part of liveness analysis. (the difficult part)
  *
@@ -1018,8 +1083,11 @@ insnwalk(NODE *p)
 
        case LTYPE:
                switch (o) {
-               case TEMP:
                case REG:
+                       if (!TESTBIT(validregs, regno(p)))
+                               break; /* never add moves */
+                       /* FALLTHROUGH */
+               case TEMP:
                        i = regno(p);
                        rr = (o == TEMP ? &nblock[i] :  &ablock[i]);
                        if (rv != rr) {
@@ -1039,9 +1107,101 @@ insnwalk(NODE *p)
        }
 }
 
-static bittype **gen, **kill, **in, **out;
-//static int ntemp, emax;
+static bittype **gen, **killed, **in, **out;
 
+#define        MAXNSPILL       100
+static int notspill[MAXNSPILL], nspill;
+
+static int
+innotspill(int n)
+{
+       int i;
+       for (i = 0; i < nspill; i++)
+               if (notspill[i] == n)
+                       return 1;
+       return 0;
+}
+
+/*
+ * Found an extended assembler node, so growel out gen/killed nodes.
+ */
+static void
+xasmionize(NODE *p, void *arg)
+{
+       int bb = *(int *)arg;
+       int cw, b;
+
+       if (p->n_op == ICON && p->n_type == STRTY)
+               return; /* dummy end marker */
+
+       cw = xasmcode(p->n_name);
+       if (XASMVAL(cw) == 'n' || XASMVAL(cw) == 'm')
+               return; /* no flow analysis */
+       p = p->n_left;
+
+       if (XASMVAL(cw) == 'g' && p->n_op != TEMP && p->n_op != REG)
+               return; /* no flow analysis */
+
+       b = regno(p);
+       if (XASMVAL(cw) == 'r' && p->n_op == TEMP) {
+               if (!innotspill(b)) {
+                       if (nspill < MAXNSPILL)
+                               notspill[nspill++] = b;
+                       else
+                               werror("MAXNSPILL overbooked");
+               }
+       }
+       if (XASMISOUT(cw)) {
+               if (p->n_op == TEMP) {
+                       b -= tempmin+MAXREGS;
+                       BITCLEAR(gen[bb], b);
+                       BITSET(killed[bb], b);
+               } else if (p->n_op == REG) {
+                       BITCLEAR(gen[bb], b);
+                       BITSET(killed[bb], b);
+               } else
+                       uerror("bad xasm node type");
+       }
+       if (XASMISINP(cw)) {
+               if (p->n_op == TEMP) {
+                       BITSET(gen[bb], (b - tempmin+MAXREGS));
+               } else if (p->n_op == REG) {
+                       BITSET(gen[bb], b);
+               } else if (optype(p->n_op) != LTYPE) {
+                       if (XASMVAL(cw) == 'r')
+                               uerror("couldn't find available register");
+                       else
+                               uerror("bad xasm node type2");
+               }
+       }
+}
+
+/*
+ * Check that given constraints are valid.
+ */
+static void
+xasmconstr(NODE *p, void *arg)
+{
+       int i;
+
+       if (p->n_op == ICON && p->n_type == STRTY)
+               return; /* no constraints */
+
+       if (strcmp(p->n_name, "cc") == 0 || strcmp(p->n_name, "memory") == 0)
+               return;
+
+       for (i = 0; i < MAXREGS; i++)
+               if (strcmp(rnames[i], p->n_name) == 0) {
+                       addalledges(&ablock[i]);
+                       return;
+               }
+
+       comperr("unsupported xasm constraint %s", p->n_name);
+}
+
+/*
+ * Set/clear long term liveness for regs and temps.
+ */
 static void
 unionize(NODE *p, int bb)
 {
@@ -1065,19 +1225,19 @@ unionize(NODE *p, int bb)
 #ifdef notyet
                        for (i = 0; i < szty(p->n_type); i++) {
                                BITCLEAR(gen[bb], (b+i));
-                               BITSET(kill[bb], (b+i));
+                               BITSET(killed[bb], (b+i));
                        }
 #else
                        i = 0;
                        BITCLEAR(gen[bb], (b+i));
-                       BITSET(kill[bb], (b+i));
+                       BITSET(killed[bb], (b+i));
 #endif
                        unionize(p->n_right, bb);
                        return;
                } else if (p->n_left->n_op == REG) {
                        int b = regno(p->n_left);
                        BITCLEAR(gen[bb], b);
-                       BITSET(kill[bb], b);
+                       BITSET(killed[bb], b);
                        unionize(p->n_right, bb);
                        return;
                }
@@ -1104,14 +1264,19 @@ LivenessAnalysis(void)
        int i, bbnum;
 
        /*
-        * generate the gen-kill sets for all basic blocks.
+        * generate the gen-killed sets for all basic blocks.
         */
        DLIST_FOREACH(bb, &bblocks, bbelem) {
                bbnum = bb->bbnum;
                for (ip = bb->last; ; ip = DLIST_PREV(ip, qelem)) {
-                       /* gen/kill is 'p', this node is 'n' */
-                       if (ip->type == IP_NODE)
-                               unionize(ip->ip_node, bbnum);
+                       /* gen/killed is 'p', this node is 'n' */
+                       if (ip->type == IP_NODE) {
+                               if (ip->ip_node->n_op == XASM)
+                                       flist(ip->ip_node->n_left,
+                                           xasmionize, &bbnum);
+                               else
+                                       unionize(ip->ip_node, bbnum);
+                       }
                        if (ip == bb->first)
                                break;
                }
@@ -1123,9 +1288,9 @@ LivenessAnalysis(void)
                        for (i = 0; i < xbits; i++)
                                if (TESTBIT(gen[bbnum], i))
                                        PRTRG(i);
-                       printf("\nkill: ");
+                       printf("\nkilled: ");
                        for (i = 0; i < xbits; i++)
-                               if (TESTBIT(kill[bbnum], i))
+                               if (TESTBIT(killed[bbnum], i))
                                        PRTRG(i);
                        printf("\n");
                }
@@ -1172,17 +1337,18 @@ Build(struct interpass *ipole)
 
        /* Just fetch space for the temporaries from stack */
        gen = alloca(nbblocks*sizeof(bittype*));
-       kill = alloca(nbblocks*sizeof(bittype*));
+       killed = alloca(nbblocks*sizeof(bittype*));
        in = alloca(nbblocks*sizeof(bittype*));
        out = alloca(nbblocks*sizeof(bittype*));
        for (i = 0; i < nbblocks; i++) {
                BITALLOC(gen[i],alloca,xbits);
-               BITALLOC(kill[i],alloca,xbits);
+               BITALLOC(killed[i],alloca,xbits);
                BITALLOC(in[i],alloca,xbits);
                BITALLOC(out[i],alloca,xbits);
        }
        BITALLOC(saved,alloca,xbits);
 
+       nspill = 0;
        LivenessAnalysis();
 
        /* register variable temporaries are live */
@@ -1202,7 +1368,7 @@ Build(struct interpass *ipole)
                again = 0;
                /* XXX - loop should be in reversed execution-order */
                DLIST_FOREACH_REVERSE(bb, &bblocks, bbelem) {
-                       int i = bb->bbnum;
+                       i = bb->bbnum;
                        SETCOPY(saved, out[i], j, xbits);
                        SLIST_FOREACH(cn, &bb->children, cfgelem) {
                                SETSET(out[i], in[cn->bblock->bbnum], j, xbits);
@@ -1210,7 +1376,7 @@ Build(struct interpass *ipole)
                        SETCMP(again, saved, out[i], j, xbits);
                        SETCOPY(saved, in[i], j, xbits);
                        SETCOPY(in[i], out[i], j, xbits);
-                       SETCLEAR(in[i], kill[i], j, xbits);
+                       SETCLEAR(in[i], killed[i], j, xbits);
                        SETSET(in[i], gen[i], j, xbits);
                        SETCMP(again, saved, in[i], j, xbits);
                }
@@ -1239,8 +1405,14 @@ Build(struct interpass *ipole)
                        live[j/NUMBITS] = 0;
                SETCOPY(live, out[i], j, xbits);
                for (ip = bb->last; ; ip = DLIST_PREV(ip, qelem)) {
-                       if (ip->type == IP_NODE)
-                               insnwalk(ip->ip_node);
+                       if (ip->type == IP_NODE) {
+                               if (ip->ip_node->n_op == XASM) {
+                                       flist(ip->ip_node->n_right,
+                                           xasmconstr, 0);
+                                       listf(ip->ip_node->n_left, setxarg);
+                               } else
+                                       insnwalk(ip->ip_node);
+                       }
                        if (ip == bb->first)
                                break;
                }
@@ -1248,7 +1420,6 @@ Build(struct interpass *ipole)
 
 #ifdef PCC_DEBUG
        if (rdebug) {
-               int i;
                struct AdjSet *w;
                ADJL *x;
                REGW *y;
@@ -1329,7 +1500,9 @@ DecrementDegree(REGW *w, int c)
 {
        int wast;
 
+#ifdef PCC_DEBUG
        RRDEBUG(("DecrementDegree: w %d, c %d\n", ASGNUM(w), c));
+#endif
 
        wast = trivially_colorable(w);
        NCLASS(w, c)--;
@@ -1354,7 +1527,9 @@ Simplify(void)
 
        w = POPWLIST(simplifyWorklist);
        PUSHWLIST(w, selectStack);
+#ifdef PCC_DEBUG
        RDEBUG(("Simplify: node %d class %d\n", ASGNUM(w), w->r_class));
+#endif
 
        l = w->r_adjList;
        for (; l; l = l->r_next) {
@@ -1376,10 +1551,10 @@ GetAlias(REGW *n)
 static int
 OK(REGW *t, REGW *r)
 {
+#ifdef PCC_DEBUG
        RDEBUG(("OK: t %d CLASS(t) %d adjSet(%d,%d)=%d\n",
            ASGNUM(t), CLASS(t), ASGNUM(t), ASGNUM(r), adjSet(t, r)));
 
-#ifdef PCC_DEBUG
        if (rdebug > 1) {
                ADJL *w;
                int ndeg = 0;
@@ -1438,14 +1613,18 @@ Conservative(REGW *u, REGW *v)
 #ifdef oldcons
        int i, ncl[NUMCLASS+1];
 
+#ifdef PCC_DEBUG
        if (CLASS(u) != CLASS(v))
                comperr("Conservative: u(%d = %d), v(%d = %d)",
                    ASGNUM(u), CLASS(u), ASGNUM(v), CLASS(v));
+#endif
 
        for (i = 0; i < NUMCLASS+1; i++)
                ncl[i] = 0;
 
+#ifdef PCC_DEBUG
        RDEBUG(("Conservative (%d,%d)\n", ASGNUM(u), ASGNUM(v)));
+#endif
 
        for (w = ADJLIST(u); w; w = w->r_next) {
                n = w->a_temp;
@@ -1540,7 +1719,9 @@ Combine(REGW *u, REGW *v)
        ADJL *l;
        REGW *t;
 
+#ifdef PCC_DEBUG
        RDEBUG(("Combine (%d,%d)\n", ASGNUM(u), ASGNUM(v)));
+#endif
 
        if (ONLIST(v) == &freezeWorklist) {
                DELWLIST(v);
@@ -1549,12 +1730,14 @@ Combine(REGW *u, REGW *v)
        }
        PUSHWLIST(v, coalescedNodes);
        ALIAS(v) = u;
+#ifdef PCC_DEBUG
        if (rdebug) { 
                printf("adjlist(%d): ", ASGNUM(v));
                for (l = ADJLIST(v); l; l = l->r_next)
                        printf("%d ", l->a_temp->nodnum);
                printf("\n");
        }
+#endif
 #if 1
 {
        MOVL *m0 = MOVELIST(v);
@@ -1592,6 +1775,7 @@ Combine(REGW *u, REGW *v)
                DELWLIST(u);
                PUSHWLIST(u, spillWorklist);
        }
+#ifdef PCC_DEBUG
 if (rdebug) {
        ADJL *w;
        printf("Combine %d class (%d): ", ASGNUM(u), CLASS(u));
@@ -1604,6 +1788,7 @@ if (rdebug) {
        }
        printf("\n");
 }
+#endif
 }
 
 static void
@@ -1621,9 +1806,11 @@ Coalesce(void)
        else
                u = x, v = y;
 
+#ifdef PCC_DEBUG
        RDEBUG(("Coalesce: src %d dst %d u %d v %d x %d y %d\n",
            ASGNUM(m->src), ASGNUM(m->dst), ASGNUM(u), ASGNUM(v),
            ASGNUM(x), ASGNUM(y)));
+#endif
 
        if (CLASS(m->src) != CLASS(m->dst))
                comperr("Coalesce: src class %d, dst class %d",
@@ -1668,8 +1855,10 @@ FreezeMoves(REGW *u)
                        v = GetAlias(x);
                else
                        v = GetAlias(y);
+#ifdef PCC_DEBUG
                RDEBUG(("FreezeMoves: u %d (%d,%d) v %d\n",
                    ASGNUM(u),ASGNUM(x),ASGNUM(y),ASGNUM(v)));
+#endif
                DLIST_REMOVE(m, link);
                PUSHMLIST(m, frozenMoves, FROZEN);
                if (ONLIST(v) != &freezeWorklist)
@@ -1697,7 +1886,9 @@ Freeze(void)
         */
        u = POPWLIST(freezeWorklist);
        PUSHWLIST(u, simplifyWorklist);
+#ifdef PCC_DEBUG
        RDEBUG(("Freeze %d\n", ASGNUM(u)));
+#endif
        FreezeMoves(u);
 }
 
@@ -1707,9 +1898,11 @@ SelectSpill(void)
        REGW *w;
 
        RDEBUG(("SelectSpill\n"));
+#ifdef PCC_DEBUG
        if (rdebug)
                DLIST_FOREACH(w, &spillWorklist, link)
                        printf("SelectSpill: %d\n", ASGNUM(w));
+#endif
 
        /* First check if we can spill register variables */
        DLIST_FOREACH(w, &spillWorklist, link) {
@@ -1720,6 +1913,8 @@ SelectSpill(void)
        if (w == &spillWorklist) {
                /* try to find another long-range variable */
                DLIST_FOREACH(w, &spillWorklist, link) {
+                       if (innotspill(w - nblock))
+                               continue;
                        if (w >= &nblock[tempmin] && w < &nblock[tempmax])
                                break;
                }
@@ -1743,7 +1938,9 @@ SelectSpill(void)
         DLIST_REMOVE(w, link);
 
        PUSHWLIST(w, simplifyWorklist);
+#ifdef PCC_DEBUG
        RDEBUG(("Freezing node %d\n", ASGNUM(w)));
+#endif
        FreezeMoves(w);
 }
 
@@ -1807,13 +2004,17 @@ AssignColors(struct interpass *ip)
        while (!WLISTEMPTY(selectStack)) {
                w = POPWLIST(selectStack);
                okColors = classmask(CLASS(w));
+#ifdef PCC_DEBUG
                RDEBUG(("classmask av %d, class %d: %x\n",
                    w->nodnum, CLASS(w), okColors));
+#endif
 
                for (x = ADJLIST(w); x; x = x->r_next) {
                        o = GetAlias(x->a_temp);
+#ifdef PCC_DEBUG
                        RRDEBUG(("Adj(%d): %d (%d)\n",
                            ASGNUM(w), ASGNUM(o), ASGNUM(x->a_temp)));
+#endif
 
                        if (ONLIST(o) == &coloredNodes ||
                            ONLIST(o) == &precolored) {
@@ -1827,32 +2028,43 @@ AssignColors(struct interpass *ip)
                }
                if (okColors == 0) {
                        PUSHWLIST(w, spilledNodes);
+#ifdef PCC_DEBUG
                        RDEBUG(("Spilling node %d\n", ASGNUM(w)));
+#endif
                } else {
                        PUSHWLIST(w, coloredNodes);
                        c = ffs(okColors)-1;
                        COLOR(w) = color2reg(c, CLASS(w));
+#ifdef PCC_DEBUG
                        RDEBUG(("Coloring %d with %s, free %x\n",
                            ASGNUM(w), rnames[COLOR(w)], okColors));
+#endif
                }
        }
        DLIST_FOREACH(w, &coalescedNodes, link) {
                REGW *ww = GetAlias(w);
                COLOR(w) = COLOR(ww);
                if (ONLIST(ww) == &spilledNodes) {
+#ifdef PCC_DEBUG
                        RDEBUG(("coalesced node %d spilled\n", w->nodnum));
+#endif
                        ww = DLIST_PREV(w, link);
                        DLIST_REMOVE(w, link);
                        PUSHWLIST(w, spilledNodes);
                        w = ww;
-               } else
+               } else {
+#ifdef PCC_DEBUG
                        RDEBUG(("Giving coalesced node %d color %s\n",
                            w->nodnum, rnames[COLOR(w)]));
+#endif
+               }
        }
 
+#ifdef PCC_DEBUG
        if (rdebug)
                DLIST_FOREACH(w, &coloredNodes, link)
                        printf("%d: color %s\n", ASGNUM(w), rnames[COLOR(w)]);
+#endif
        if (DLIST_ISEMPTY(&spilledNodes, link)) {
                struct interpass *ip2;
                DLIST_FOREACH(ip2, ip, qelem)
@@ -1869,6 +2081,7 @@ static REGW *spole;
 static void
 longtemp(NODE *p)
 {
+       NODE *l, *r;
        REGW *w;
 
        if (p->n_op != TEMP)
@@ -1881,9 +2094,10 @@ longtemp(NODE *p)
                        w->r_color = BITOOR(freetemp(szty(p->n_type)));
                        w->r_class = 1;
                }
-               p->n_op = OREG;
-               p->n_lval = w->r_color;
-               p->n_rval = FPREG;
+               l = mklnode(REG, 0, FPREG, INCREF(p->n_type));
+               r = mklnode(ICON, w->r_color, 0, INT);
+               p->n_left = mkbinode(PLUS, l, r, INCREF(p->n_type));
+               p->n_op = UMUL;
                p->n_regw = NULL;
                break;
        }
@@ -1910,10 +2124,14 @@ shorttemp(NODE *p)
                /* XXX - use canaddr() */
                if (p->n_op == OREG || p->n_op == NAME) {
                        DLIST_REMOVE(w, link);
+#ifdef PCC_DEBUG
                        RDEBUG(("Node %d already in memory\n", ASGNUM(w)));
+#endif
                        break;
                }
+#ifdef PCC_DEBUG
                RDEBUG(("rewriting node %d\n", ASGNUM(w)));
+#endif
 
                off = BITOOR(freetemp(szty(p->n_type)));
                l = mklnode(OREG, off, FPREG, p->n_type);
@@ -2118,7 +2336,7 @@ prtreg(FILE *fp, NODE *p)
 {
        int i, n = p->n_su == -1 ? 0 : ncnt(table[TBLIDX(p->n_su)].needs);
 
-       if (use_regw) {
+       if (use_regw || p->n_reg > 0x40000000 || p->n_reg < 0) {
                fprintf(fp, "TEMP ");
                if (p->n_regw != NULL) {
                        for (i = 0; i < n+1; i++)
@@ -2246,7 +2464,8 @@ onlyperm: /* XXX - should not have to redo all */
                        continue;
                nodepole = ip->ip_node;
                thisline = ip->lineno;
-               geninsn(ip->ip_node, FOREFF);
+               if (ip->ip_node->n_op != XASM)
+                       geninsn(ip->ip_node, FOREFF);
                nsucomp(ip->ip_node);
                walkf(ip->ip_node, traclass);
        }
@@ -2254,9 +2473,13 @@ onlyperm: /* XXX - should not have to redo all */
        RDEBUG(("nsucomp allocated %d temps (%d,%d)\n", 
            tempmax-tempmin, tempmin, tempmax));
 
+#ifdef PCC_DEBUG
        use_regw = 1;
+#endif
        RPRINTIP(ipole);
+#ifdef PCC_DEBUG
        use_regw = 0;
+#endif
        RDEBUG(("ngenregs: numtemps %d (%d, %d)\n", tempmax-tempmin,
                    tempmin, tempmax));
 
@@ -2322,7 +2545,7 @@ onlyperm: /* XXX - should not have to redo all */
                /*
                 * If the original color of this permreg is used for
                 * coloring another register, swap them to avoid
-                * unneccessary moves.
+                * unnecessary moves.
                 */
                for (j = i+1; j < NPERMREG-1; j++) {
                        if (nblock[j+tempmin].r_color != permregs[i])
index 2874965..60493c8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: local.c,v 1.5 2008/01/12 17:30:42 ragge Exp $ */
+/*     $OpenBSD: local.c,v 1.6 2008/08/17 18:40:13 ragge Exp $ */
 /*
  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
  *
@@ -503,3 +503,7 @@ fixdef(struct symtab *sp)
 {
 }
 
+void
+pass1_lastchance(struct interpass *ip)
+{
+}
index 18cc926..8d6fdfc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: local2.c,v 1.6 2007/12/22 22:56:31 stefan Exp $       */
+/*     $OpenBSD: local2.c,v 1.7 2008/08/17 18:40:13 ragge Exp $        */
 /*
  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
  *
@@ -1023,3 +1023,12 @@ void
 mflags(char *str)
 {
 }
+/*
+ * Do something target-dependent for xasm arguments.
+ * Supposed to find target-specific constraints and rewrite them.
+ */
+int
+myxasm(struct interpass *ip, NODE *p)
+{
+       return 0;
+}