scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

commit 687ff1f6ffd8929e0ccb55336225bb96292e8150
parent d9be6267deff0c8d91702a8a62ddf0dfb03ac713
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  4 Dec 2018 10:18:41 +0000

Big tree rework

Diffstat:
M.gitignore | 25++++---------------------
MMakefile | 34++++++++++++++++------------------
Dar/Makefile | 22----------------------
Dar/deps.mk | 7-------
Dar/main.c | 643-------------------------------------------------------------------------------
Das/Makefile | 29-----------------------------
Das/deps.mk | 46----------------------------------------------
Das/expr.c | 303-------------------------------------------------------------------------------
Das/gentbl.awk | 112-------------------------------------------------------------------------------
Das/gentbl.sh | 33---------------------------------
Das/ins.c | 249-------------------------------------------------------------------------------
Das/main.c | 138-------------------------------------------------------------------------------
Das/myro.c | 204-------------------------------------------------------------------------------
Das/parser.c | 482-------------------------------------------------------------------------------
Das/symbol.c | 291------------------------------------------------------------------------------
Das/target/amd64.mk | 8--------
Das/target/i286.mk | 8--------
Das/target/i386.mk | 8--------
Das/target/x80/ins.c | 600-------------------------------------------------------------------------------
Das/target/x80/z80.c | 64----------------------------------------------------------------
Das/target/x86/amd64.c | 12------------
Das/target/x86/i286.c | 53-----------------------------------------------------
Das/target/x86/i386.c | 100-------------------------------------------------------------------------------
Das/target/x86/ins.c | 301-------------------------------------------------------------------------------
Das/target/z80.mk | 8--------
Dcc1/Makefile | 32--------------------------------
Dcc1/builtin.c | 121-------------------------------------------------------------------------------
Dcc1/code.c | 550-------------------------------------------------------------------------------
Dcc1/cpp.c | 839-------------------------------------------------------------------------------
Dcc1/decl.c | 967-------------------------------------------------------------------------------
Dcc1/deps.mk | 45---------------------------------------------
Dcc1/error.c | 85-------------------------------------------------------------------------------
Dcc1/expr.c | 1185-------------------------------------------------------------------------------
Dcc1/fold.c | 685-------------------------------------------------------------------------------
Dcc1/init.c | 378-------------------------------------------------------------------------------
Dcc1/lex.c | 801-------------------------------------------------------------------------------
Dcc1/main.c | 102-------------------------------------------------------------------------------
Dcc1/stmt.c | 386-------------------------------------------------------------------------------
Dcc1/symbol.c | 353-------------------------------------------------------------------------------
Dcc1/target/amd64-sysv/arch.c | 220-------------------------------------------------------------------------------
Dcc1/target/amd64-sysv/arch.mk | 5-----
Dcc1/target/arm64-sysv/arch.c | 220-------------------------------------------------------------------------------
Dcc1/target/arm64-sysv/arch.mk | 5-----
Dcc1/target/i386-sysv/arch.c | 221-------------------------------------------------------------------------------
Dcc1/target/i386-sysv/arch.mk | 5-----
Dcc1/target/z80-scc/arch.c | 219-------------------------------------------------------------------------------
Dcc1/target/z80-scc/arch.mk | 5-----
Dcc1/types.c | 438-------------------------------------------------------------------------------
Dcc2/Makefile | 35-----------------------------------
Dcc2/code.c | 133-------------------------------------------------------------------------------
Dcc2/deps.mk | 61-------------------------------------------------------------
Dcc2/main.c | 70----------------------------------------------------------------------
Dcc2/node.c | 142-------------------------------------------------------------------------------
Dcc2/optm.c | 9---------
Dcc2/parser.c | 722-------------------------------------------------------------------------------
Dcc2/peep.c | 8--------
Dcc2/symbol.c | 92-------------------------------------------------------------------------------
Dcc2/target/amd64-sysv/cgen.c | 15---------------
Dcc2/target/amd64-sysv/code.c | 210-------------------------------------------------------------------------------
Dcc2/target/amd64-sysv/optm.c | 10----------
Dcc2/target/amd64-sysv/target.mk | 9---------
Dcc2/target/amd64-sysv/types.c | 93-------------------------------------------------------------------------------
Dcc2/target/i386-sysv/cgen.c | 15---------------
Dcc2/target/i386-sysv/code.c | 208-------------------------------------------------------------------------------
Dcc2/target/i386-sysv/optm.c | 10----------
Dcc2/target/i386-sysv/target.mk | 9---------
Dcc2/target/i386-sysv/types.c | 94-------------------------------------------------------------------------------
Dcc2/target/qbe/cgen.c | 728-------------------------------------------------------------------------------
Dcc2/target/qbe/code.c | 568-------------------------------------------------------------------------------
Dcc2/target/qbe/optm.c | 57---------------------------------------------------------
Dcc2/target/qbe_amd64-sysv/target.mk | 9---------
Dcc2/target/qbe_arm64-sysv/target.mk | 5-----
Dcc2/target/z80-scc/cgen.c | 160-------------------------------------------------------------------------------
Dcc2/target/z80-scc/code.c | 228-------------------------------------------------------------------------------
Dcc2/target/z80-scc/optm.c | 10----------
Dcc2/target/z80-scc/target.mk | 9---------
Dcc2/target/z80-scc/types.c | 94-------------------------------------------------------------------------------
Dconfig.mk | 30------------------------------
Dconfig.sh | 16----------------
Aconfig/amd64-linux.mk | 8++++++++
Aconfig/i386-linux.mk | 5+++++
Ddriver/Makefile | 10----------
Ddriver/posix/Makefile | 42------------------------------------------
Dinc/Makefile | 37-------------------------------------
Dinc/incdep.mk | 7-------
Dinc/inclst.mk | 4----
Ainclude/assert.h | 8++++++++
Ainclude/bits/.gitignore | 1+
Ainclude/bits/amd64/arch/limits.h | 18++++++++++++++++++
Ainclude/bits/amd64/arch/setjmp.h | 1+
Ainclude/bits/amd64/arch/stddef.h | 14++++++++++++++
Ainclude/bits/amd64/arch/stdint.h | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/bits/amd64/arch/stdio.h | 15+++++++++++++++
Ainclude/bits/amd64/arch/stdlib.h | 14++++++++++++++
Ainclude/bits/amd64/arch/string.h | 6++++++
Ainclude/bits/amd64/arch/time.h | 8++++++++
Ainclude/bits/arm32/arch/limits.h | 18++++++++++++++++++
Ainclude/bits/arm32/arch/setjmp.h | 1+
Ainclude/bits/arm32/arch/stddef.h | 9+++++++++
Ainclude/bits/arm32/arch/stdint.h | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/bits/arm32/arch/stdio.h | 15+++++++++++++++
Ainclude/bits/arm32/arch/stdlib.h | 14++++++++++++++
Ainclude/bits/arm32/arch/string.h | 6++++++
Ainclude/bits/arm32/arch/time.h | 8++++++++
Ainclude/bits/arm64/arch/limits.h | 18++++++++++++++++++
Ainclude/bits/arm64/arch/setjmp.h | 1+
Ainclude/bits/arm64/arch/stddef.h | 9+++++++++
Ainclude/bits/arm64/arch/stdint.h | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/bits/arm64/arch/stdio.h | 15+++++++++++++++
Ainclude/bits/arm64/arch/stdlib.h | 14++++++++++++++
Ainclude/bits/arm64/arch/string.h | 6++++++
Ainclude/bits/arm64/arch/time.h | 8++++++++
Ainclude/bits/dragonfly/sys.h | 19+++++++++++++++++++
Ainclude/bits/dragonfly/sys/signal.h | 27+++++++++++++++++++++++++++
Ainclude/bits/i386/arch/limits.h | 18++++++++++++++++++
Ainclude/bits/i386/arch/stddef.h | 14++++++++++++++
Ainclude/bits/i386/arch/stdint.h | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/bits/i386/arch/stdio.h | 15+++++++++++++++
Ainclude/bits/i386/arch/stdlib.h | 14++++++++++++++
Ainclude/bits/i386/arch/string.h | 5+++++
Ainclude/bits/i386/arch/time.h | 8++++++++
Ainclude/bits/linux/sys.h | 19+++++++++++++++++++
Ainclude/bits/linux/sys/signal.h | 27+++++++++++++++++++++++++++
Ainclude/bits/netbsd/sys.h | 19+++++++++++++++++++
Ainclude/bits/netbsd/sys/signal.h | 27+++++++++++++++++++++++++++
Ainclude/bits/openbsd/sys.h | 19+++++++++++++++++++
Ainclude/bits/openbsd/sys/signal.h | 27+++++++++++++++++++++++++++
Ainclude/bits/z80/arch/limits.h | 18++++++++++++++++++
Ainclude/bits/z80/arch/stddef.h | 14++++++++++++++
Ainclude/bits/z80/arch/stdint.h | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/bits/z80/arch/stdio.h | 15+++++++++++++++
Ainclude/bits/z80/arch/stdlib.h | 14++++++++++++++
Ainclude/bits/z80/arch/string.h | 5+++++
Ainclude/bits/z80/arch/time.h | 8++++++++
Ainclude/ctype.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Ainclude/errno.h | 6++++++
Ainclude/float.h | 1+
Ainclude/limits.h | 8++++++++
Ainclude/locale.h | 39+++++++++++++++++++++++++++++++++++++++
Ainclude/math.h | 4++++
Ainclude/scc/scc/.gitignore | 5+++++
Ainclude/scc/scc/Makefile | 42++++++++++++++++++++++++++++++++++++++++++
Rinc/ar.h -> include/scc/scc/ar.h | 0
Rinc/arg.h -> include/scc/scc/arg.h | 0
Rinc/coff32/aouthdr.h -> include/scc/scc/coff32/aouthdr.h | 0
Rinc/coff32/coff32.h -> include/scc/scc/coff32/coff32.h | 0
Rinc/coff32/filehdr.h -> include/scc/scc/coff32/filehdr.h | 0
Rinc/coff32/linenum.h -> include/scc/scc/coff32/linenum.h | 0
Rinc/coff32/reloc.h -> include/scc/scc/coff32/reloc.h | 0
Rinc/coff32/scnhdr.h -> include/scc/scc/coff32/scnhdr.h | 0
Rinc/coff32/syms.h -> include/scc/scc/coff32/syms.h | 0
Rinc/c89/cstd.h -> include/scc/scc/cstd-c89.h | 0
Rinc/c99/cstd.h -> include/scc/scc/cstd-c99.h | 0
Rinc/ldflags.def.h -> include/scc/scc/ldflags.def.h | 0
Rinc/myro.h -> include/scc/scc/myro.h | 0
Rinc/scc.h -> include/scc/scc/scc.h | 0
Rinc/syscrts.def.h -> include/scc/scc/syscrts.def.h | 0
Rinc/sysincludes.def.h -> include/scc/scc/sysincludes.def.h | 0
Rinc/syslibs.def.h -> include/scc/scc/syslibs.def.h | 0
Ainclude/setjmp.h | 11+++++++++++
Ainclude/signal.h | 9+++++++++
Ainclude/stdarg.h | 10++++++++++
Ainclude/stdbool.h | 9+++++++++
Ainclude/stddef.h | 12++++++++++++
Ainclude/stdint.h | 6++++++
Ainclude/stdio.h | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/stdlib.h | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/string.h | 34++++++++++++++++++++++++++++++++++
Ainclude/time.h | 43+++++++++++++++++++++++++++++++++++++++++++
Ainclude/wchar.h | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/wctype.h | 30++++++++++++++++++++++++++++++
Dld/Makefile | 23-----------------------
Dld/coff32.c | 403-------------------------------------------------------------------------------
Dld/deps.mk | 15---------------
Dld/main.c | 288-------------------------------------------------------------------------------
Dld/obj.c | 153-------------------------------------------------------------------------------
Dlib/Makefile | 15---------------
Dlib/c/Makefile | 29-----------------------------
Dlib/c/arch/arm32/linux/time.c | 1-
Dlib/c/arch/arm32/longjmp.s | 11-----------
Dlib/c/arch/arm32/setjmp.s | 9---------
Dlib/c/arch/arm64/Makefile | 14--------------
Dlib/c/arch/arm64/linux/.gitignore | 10----------
Dlib/c/arch/arm64/linux/Makefile | 37-------------------------------------
Dlib/c/arch/arm64/linux/_cerrno.s | 13-------------
Dlib/c/arch/arm64/linux/_getheap.s | 6------
Dlib/c/arch/arm64/linux/_open.c | 13-------------
Dlib/c/arch/arm64/linux/_sigaction.c | 14--------------
Dlib/c/arch/arm64/linux/_tzone.c | 1-
Dlib/c/arch/arm64/linux/gensys.sh | 21---------------------
Dlib/c/arch/arm64/linux/getenv.c | 1-
Dlib/c/arch/arm64/linux/raise.c | 1-
Dlib/c/arch/arm64/linux/signal.c | 1-
Dlib/c/arch/arm64/linux/syscall.lst | 11-----------
Dlib/c/arch/arm64/linux/time.c | 1-
Dlib/c/arch/arm64/longjmp.s | 22----------------------
Dlib/c/arch/arm64/setjmp.s | 20--------------------
Dlib/c/arch/generrno.sh | 35-----------------------------------
Dlib/c/arch/generrstr.sh | 23-----------------------
Dlib/c/arch/mkerrstr | 24------------------------
Dlib/c/arch/posix/_tzone.c | 27---------------------------
Dlib/c/arch/posix/getenv.c | 18------------------
Dlib/c/arch/posix/geterrno.sh | 8--------
Dlib/c/arch/posix/raise.c | 11-----------
Dlib/c/arch/posix/signal.c | 17-----------------
Dlib/c/arch/posix/time.c | 21---------------------
Dlib/c/arch/rules.mk | 4----
Dlib/c/assert/Makefile | 10----------
Dlib/c/assert/__assert.c | 9---------
Dlib/c/assert/assert.c | 13-------------
Dlib/c/ctype/Makefile | 24------------------------
Dlib/c/ctype/ctype.c | 22----------------------
Dlib/c/ctype/isalnum.c | 8--------
Dlib/c/ctype/isalpha.c | 8--------
Dlib/c/ctype/isascii.c | 8--------
Dlib/c/ctype/isblank.c | 7-------
Dlib/c/ctype/iscntrl.c | 8--------
Dlib/c/ctype/isdigit.c | 8--------
Dlib/c/ctype/isgraph.c | 8--------
Dlib/c/ctype/islower.c | 8--------
Dlib/c/ctype/isprint.c | 8--------
Dlib/c/ctype/ispunct.c | 8--------
Dlib/c/ctype/isspace.c | 8--------
Dlib/c/ctype/isupper.c | 8--------
Dlib/c/ctype/isxdigit.c | 8--------
Dlib/c/ctype/tolower.c | 9---------
Dlib/c/ctype/toupper.c | 8--------
Dlib/c/libc.h | 42------------------------------------------
Dlib/c/locale/Makefile | 10----------
Dlib/c/locale/localeconv.c | 29-----------------------------
Dlib/c/locale/setlocale.c | 16----------------
Dlib/c/mklst | 12------------
Dlib/c/stdio/Makefile | 47-----------------------------------------------
Dlib/c/stdio/__getc.c | 39---------------------------------------
Dlib/c/stdio/__iob.c | 20--------------------
Dlib/c/stdio/__putc.c | 78------------------------------------------------------------------------------
Dlib/c/stdio/_allocbuf.c | 21---------------------
Dlib/c/stdio/_flsbuf.c | 23-----------------------
Dlib/c/stdio/_fpopen.c | 75---------------------------------------------------------------------------
Dlib/c/stdio/clearerr.c | 8--------
Dlib/c/stdio/fclose.c | 32--------------------------------
Dlib/c/stdio/feof.c | 8--------
Dlib/c/stdio/ferror.c | 8--------
Dlib/c/stdio/fgetc.c | 8--------
Dlib/c/stdio/fgets.c | 19-------------------
Dlib/c/stdio/fopen.c | 23-----------------------
Dlib/c/stdio/fprintf.c | 15---------------
Dlib/c/stdio/fputc.c | 8--------
Dlib/c/stdio/fputs.c | 12------------
Dlib/c/stdio/fread.c | 25-------------------------
Dlib/c/stdio/freopen.c | 14--------------
Dlib/c/stdio/fseek.c | 26--------------------------
Dlib/c/stdio/ftell.c | 27---------------------------
Dlib/c/stdio/fwrite.c | 24------------------------
Dlib/c/stdio/getc.c | 8--------
Dlib/c/stdio/getchar.c | 8--------
Dlib/c/stdio/gets.c | 17-----------------
Dlib/c/stdio/perror.c | 16----------------
Dlib/c/stdio/printf.c | 15---------------
Dlib/c/stdio/putc.c | 8--------
Dlib/c/stdio/putchar.c | 8--------
Dlib/c/stdio/puts.c | 12------------
Dlib/c/stdio/rewind.c | 10----------
Dlib/c/stdio/setbuf.c | 8--------
Dlib/c/stdio/setvbuf.c | 48------------------------------------------------
Dlib/c/stdio/snprintf.c | 16----------------
Dlib/c/stdio/sprintf.c | 16----------------
Dlib/c/stdio/tmpnam.c | 31-------------------------------
Dlib/c/stdio/vfprintf.c | 362-------------------------------------------------------------------------------
Dlib/c/stdio/vprintf.c | 12------------
Dlib/c/stdio/vsnprintf.c | 25-------------------------
Dlib/c/stdio/vsprintf.c | 12------------
Dlib/c/stdlib/Makefile | 25-------------------------
Dlib/c/stdlib/abort.c | 10----------
Dlib/c/stdlib/abs.c | 8--------
Dlib/c/stdlib/atexit.c | 17-----------------
Dlib/c/stdlib/atoi.c | 25-------------------------
Dlib/c/stdlib/atol.c | 26--------------------------
Dlib/c/stdlib/atoll.c | 26--------------------------
Dlib/c/stdlib/bsearch.c | 26--------------------------
Dlib/c/stdlib/calloc.c | 18------------------
Dlib/c/stdlib/errno.c | 1-
Dlib/c/stdlib/exit.c | 13-------------
Dlib/c/stdlib/labs.c | 8--------
Dlib/c/stdlib/llabs.c | 8--------
Dlib/c/stdlib/malloc.c | 158-------------------------------------------------------------------------------
Dlib/c/stdlib/malloc.h | 16----------------
Dlib/c/stdlib/qsort.c | 68--------------------------------------------------------------------
Dlib/c/stdlib/rand.c | 18------------------
Dlib/c/stdlib/realloc.c | 68--------------------------------------------------------------------
Dlib/c/stdlib/strtoull.c | 64----------------------------------------------------------------
Dlib/c/string/Makefile | 31-------------------------------
Dlib/c/string/memchr.c | 12------------
Dlib/c/string/memcmp.c | 14--------------
Dlib/c/string/memcpy.c | 13-------------
Dlib/c/string/memmove.c | 18------------------
Dlib/c/string/memset.c | 12------------
Dlib/c/string/strcat.c | 14--------------
Dlib/c/string/strchr.c | 10----------
Dlib/c/string/strcmp.c | 10----------
Dlib/c/string/strcoll.c | 10----------
Dlib/c/string/strcpy.c | 12------------
Dlib/c/string/strcspn.c | 21---------------------
Dlib/c/string/strerror.c | 11-----------
Dlib/c/string/strlen.c | 12------------
Dlib/c/string/strncat.c | 15---------------
Dlib/c/string/strncmp.c | 14--------------
Dlib/c/string/strncpy.c | 14--------------
Dlib/c/string/strnlen.c | 13-------------
Dlib/c/string/strpbrk.c | 20--------------------
Dlib/c/string/strrchr.c | 14--------------
Dlib/c/string/strspn.c | 21---------------------
Dlib/c/string/strstr.c | 18------------------
Dlib/c/string/strtok.c | 25-------------------------
Dlib/c/string/strxfrm.c | 12------------
Dlib/c/syscall.h | 8--------
Dlib/c/time/Makefile | 16----------------
Dlib/c/time/_daysyear.c | 30------------------------------
Dlib/c/time/asctime.c | 12------------
Dlib/c/time/ctime.c | 8--------
Dlib/c/time/difftime.c | 8--------
Dlib/c/time/gmtime.c | 35-----------------------------------
Dlib/c/time/localtime.c | 21---------------------
Dlib/c/time/mktime.c | 112-------------------------------------------------------------------------------
Dlib/c/time/strftime.c | 246-------------------------------------------------------------------------------
Dlib/coff32/Makefile | 22----------------------
Dlib/coff32/coff32_pack_aout.c | 9---------
Dlib/coff32/coff32_pack_ent.c | 20--------------------
Dlib/coff32/coff32_pack_hdr.c | 21---------------------
Dlib/coff32/coff32_pack_scn.c | 24------------------------
Dlib/coff32/coff32_unpack_aout.c | 9---------
Dlib/coff32/coff32_unpack_ent.c | 20--------------------
Dlib/coff32/coff32_unpack_hdr.c | 22----------------------
Dlib/coff32/coff32_unpack_scn.c | 24------------------------
Dlib/coff32/deps.mk | 17-----------------
Dlib/coff32/libdep.mk | 4----
Dlib/coff32/objlst.mk | 9---------
Dlib/crt/Makefile | 14--------------
Dlib/crt/amd64-sysv-linux/Makefile | 9---------
Dlib/crt/amd64-sysv-linux/crt.s | 8--------
Dlib/crt/amd64-sysv-netbsd/Makefile | 9---------
Dlib/crt/amd64-sysv-netbsd/crt.s | 30------------------------------
Dlib/crt/amd64-sysv-openbsd/Makefile | 9---------
Dlib/crt/amd64-sysv-openbsd/crt.s | 18------------------
Dlib/crt/common.mk | 8--------
Dlib/crt/i386-sysv-linux/crt.s | 1-
Dlib/crt/i386-sysv-openbsd/crt.s | 1-
Dlib/crt/z80-scc-none/crt.s | 8--------
Dlib/scc/Makefile | 21---------------------
Dlib/scc/alloc.c | 112-------------------------------------------------------------------------------
Dlib/scc/bpack.c | 64----------------------------------------------------------------
Dlib/scc/bunpack.c | 71-----------------------------------------------------------------------
Dlib/scc/casecmp.c | 11-----------
Dlib/scc/debug.c | 20--------------------
Dlib/scc/deps.mk | 18------------------
Dlib/scc/die.c | 20--------------------
Dlib/scc/libdep.mk | 4----
Dlib/scc/lpack.c | 64----------------------------------------------------------------
Dlib/scc/lunpack.c | 71-----------------------------------------------------------------------
Dlib/scc/newitem.c | 12------------
Dlib/scc/objlst.mk | 16----------------
Dlib/scc/rmyro.c | 94-------------------------------------------------------------------------------
Dlib/scc/wmyro.c | 86-------------------------------------------------------------------------------
Dlib/scc/xcalloc.c | 13-------------
Dlib/scc/xmalloc.c | 13-------------
Dlib/scc/xrealloc.c | 13-------------
Dlib/scc/xstrdup.c | 12------------
Dmkdep.sh | 19-------------------
Dnm/Makefile | 22----------------------
Dnm/coff32.c | 312-------------------------------------------------------------------------------
Dnm/deps.mk | 12------------
Dnm/formats.c | 13-------------
Dnm/main.c | 272-------------------------------------------------------------------------------
Dnm/nm.h | 14--------------
Dobjdump/Makefile | 20--------------------
Dobjdump/deps.mk | 4----
Dobjdump/main.c | 333-------------------------------------------------------------------------------
Droot/bin/README | 1-
Droot/include/scc/assert.h | 8--------
Droot/include/scc/bits/.gitignore | 1-
Droot/include/scc/bits/amd64/arch/limits.h | 18------------------
Droot/include/scc/bits/amd64/arch/setjmp.h | 1-
Droot/include/scc/bits/amd64/arch/stddef.h | 14--------------
Droot/include/scc/bits/amd64/arch/stdint.h | 102-------------------------------------------------------------------------------
Droot/include/scc/bits/amd64/arch/stdio.h | 15---------------
Droot/include/scc/bits/amd64/arch/stdlib.h | 14--------------
Droot/include/scc/bits/amd64/arch/string.h | 6------
Droot/include/scc/bits/amd64/arch/time.h | 8--------
Droot/include/scc/bits/arm32/arch/limits.h | 18------------------
Droot/include/scc/bits/arm32/arch/setjmp.h | 1-
Droot/include/scc/bits/arm32/arch/stddef.h | 9---------
Droot/include/scc/bits/arm32/arch/stdint.h | 96-------------------------------------------------------------------------------
Droot/include/scc/bits/arm32/arch/stdio.h | 15---------------
Droot/include/scc/bits/arm32/arch/stdlib.h | 14--------------
Droot/include/scc/bits/arm32/arch/string.h | 6------
Droot/include/scc/bits/arm32/arch/time.h | 8--------
Droot/include/scc/bits/arm64/arch/limits.h | 18------------------
Droot/include/scc/bits/arm64/arch/setjmp.h | 1-
Droot/include/scc/bits/arm64/arch/stddef.h | 9---------
Droot/include/scc/bits/arm64/arch/stdint.h | 96-------------------------------------------------------------------------------
Droot/include/scc/bits/arm64/arch/stdio.h | 15---------------
Droot/include/scc/bits/arm64/arch/stdlib.h | 14--------------
Droot/include/scc/bits/arm64/arch/string.h | 6------
Droot/include/scc/bits/arm64/arch/time.h | 8--------
Droot/include/scc/bits/dragonfly/sys.h | 19-------------------
Droot/include/scc/bits/dragonfly/sys/signal.h | 27---------------------------
Droot/include/scc/bits/i386/arch/limits.h | 18------------------
Droot/include/scc/bits/i386/arch/stddef.h | 14--------------
Droot/include/scc/bits/i386/arch/stdint.h | 115-------------------------------------------------------------------------------
Droot/include/scc/bits/i386/arch/stdio.h | 15---------------
Droot/include/scc/bits/i386/arch/stdlib.h | 14--------------
Droot/include/scc/bits/i386/arch/string.h | 5-----
Droot/include/scc/bits/i386/arch/time.h | 8--------
Droot/include/scc/bits/linux/sys.h | 19-------------------
Droot/include/scc/bits/linux/sys/signal.h | 27---------------------------
Droot/include/scc/bits/netbsd/sys.h | 19-------------------
Droot/include/scc/bits/netbsd/sys/signal.h | 27---------------------------
Droot/include/scc/bits/openbsd/sys.h | 19-------------------
Droot/include/scc/bits/openbsd/sys/signal.h | 27---------------------------
Droot/include/scc/bits/z80/arch/limits.h | 18------------------
Droot/include/scc/bits/z80/arch/stddef.h | 14--------------
Droot/include/scc/bits/z80/arch/stdint.h | 115-------------------------------------------------------------------------------
Droot/include/scc/bits/z80/arch/stdio.h | 15---------------
Droot/include/scc/bits/z80/arch/stdlib.h | 14--------------
Droot/include/scc/bits/z80/arch/string.h | 5-----
Droot/include/scc/bits/z80/arch/time.h | 8--------
Droot/include/scc/ctype.h | 45---------------------------------------------
Droot/include/scc/errno.h | 6------
Droot/include/scc/float.h | 1-
Droot/include/scc/limits.h | 8--------
Droot/include/scc/locale.h | 39---------------------------------------
Droot/include/scc/math.h | 4----
Droot/include/scc/setjmp.h | 11-----------
Droot/include/scc/signal.h | 9---------
Droot/include/scc/stdarg.h | 10----------
Droot/include/scc/stdbool.h | 9---------
Droot/include/scc/stddef.h | 12------------
Droot/include/scc/stdint.h | 6------
Droot/include/scc/stdio.h | 123-------------------------------------------------------------------------------
Droot/include/scc/stdlib.h | 69---------------------------------------------------------------------
Droot/include/scc/string.h | 34----------------------------------
Droot/include/scc/time.h | 43-------------------------------------------
Droot/include/scc/wchar.h | 92-------------------------------------------------------------------------------
Droot/include/scc/wctype.h | 30------------------------------
Droot/lib/scc/amd64-sysv-linux/README | 1-
Droot/lib/scc/amd64-sysv-netbsd/README | 1-
Droot/lib/scc/amd64-sysv-openbsd/README | 1-
Droot/lib/scc/i386-sysv-linux/README | 1-
Droot/lib/scc/i386-sysv-openbsd/README | 1-
Droot/lib/scc/z80-scc-none/README | 1-
Droot/libexec/scc/README | 1-
Drules.mk | 37-------------------------------------
Ascripts/libc-proto | 10++++++++++
Ascripts/mkdep | 22++++++++++++++++++++++
Ascripts/rules.mk | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Makefile | 20++++++++++++++++++++
Asrc/ar/Makefile | 22++++++++++++++++++++++
Asrc/ar/deps.mk | 5+++++
Asrc/ar/main.c | 643+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rar/posix/driver.c -> src/ar/posix/driver.c | 0
Rar/posix/driver.h -> src/ar/posix/driver.h | 0
Asrc/as/Makefile | 33+++++++++++++++++++++++++++++++++
Ras/as.h -> src/as/as.h | 0
Asrc/as/deps.mk | 33+++++++++++++++++++++++++++++++++
Asrc/as/expr.c | 303+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/as/ins.c | 249+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/as/main.c | 138+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/as/mktbl | 32++++++++++++++++++++++++++++++++
Asrc/as/mktbl.awk | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/as/myro.c | 204+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/as/parser.c | 482+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/as/symbol.c | 291++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/as/target/amd64.mk | 10++++++++++
Asrc/as/target/i286.mk | 10++++++++++
Asrc/as/target/i386.mk | 10++++++++++
Asrc/as/target/x80/.gitignore | 1+
Asrc/as/target/x80/ins.c | 601+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ras/target/x80/proc.h -> src/as/target/x80/proc.h | 0
Ras/target/x80/rules.dat -> src/as/target/x80/rules.dat | 0
Ras/target/x80/x80.dat -> src/as/target/x80/x80.dat | 0
Asrc/as/target/x80/z80.c | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/as/target/x86/.gitignore | 3+++
Asrc/as/target/x86/amd64.c | 13+++++++++++++
Asrc/as/target/x86/i286.c | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/as/target/x86/i386.c | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/as/target/x86/ins.c | 302++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ras/target/x86/nasm.dat -> src/as/target/x86/nasm.dat | 0
Ras/target/x86/proc.h -> src/as/target/x86/proc.h | 0
Ras/target/x86/rules.dat -> src/as/target/x86/rules.dat | 0
Ras/target/x86/x86.dat -> src/as/target/x86/x86.dat | 0
Asrc/as/target/z80.mk | 10++++++++++
Asrc/cc1/Makefile | 38++++++++++++++++++++++++++++++++++++++
Rcc1/TODO -> src/cc1/TODO | 0
Asrc/cc1/builtin.c | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rcc1/cc1.h -> src/cc1/cc1.h | 0
Asrc/cc1/code.c | 550+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/cpp.c | 839+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/decl.c | 967+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/deps.mk | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/error.c | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/expr.c | 1185+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/fold.c | 685+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/init.c | 378+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rcc1/ir.md -> src/cc1/ir.md | 0
Asrc/cc1/lex.c | 801+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/main.c | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/stmt.c | 386+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/symbol.c | 353+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/target/amd64-sysv/arch.c | 220+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/target/amd64-sysv/arch.mk | 4++++
Asrc/cc1/target/arm64-sysv/arch.c | 220+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/target/arm64-sysv/arch.mk | 4++++
Asrc/cc1/target/i386-sysv/arch.c | 221+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/target/i386-sysv/arch.mk | 4++++
Asrc/cc1/target/z80-scc/arch.c | 219+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc1/target/z80-scc/arch.mk | 4++++
Asrc/cc1/types.c | 438+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc2/.gitignore | 1+
Asrc/cc2/Makefile | 40++++++++++++++++++++++++++++++++++++++++
Rcc2/cc2.h -> src/cc2/cc2.h | 0
Asrc/cc2/code.c | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc2/deps.mk | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rcc2/generror.awk -> src/cc2/generror.awk | 0
Asrc/cc2/main.c | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc2/node.c | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc2/optm.c | 9+++++++++
Asrc/cc2/parser.c | 722+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc2/peep.c | 8++++++++
Asrc/cc2/symbol.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rcc2/target/amd64-sysv/arch.h -> src/cc2/target/amd64-sysv/arch.h | 0
Asrc/cc2/target/amd64-sysv/cgen.c | 15+++++++++++++++
Asrc/cc2/target/amd64-sysv/code.c | 211+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc2/target/amd64-sysv/optm.c | 11+++++++++++
Asrc/cc2/target/amd64-sysv/target.mk | 8++++++++
Asrc/cc2/target/amd64-sysv/types.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rcc2/target/arm64-sysv/types.c -> src/cc2/target/arm64-sysv/types.c | 0
Rcc2/target/i386-sysv/arch.h -> src/cc2/target/i386-sysv/arch.h | 0
Asrc/cc2/target/i386-sysv/cgen.c | 16++++++++++++++++
Asrc/cc2/target/i386-sysv/code.c | 209+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc2/target/i386-sysv/optm.c | 11+++++++++++
Asrc/cc2/target/i386-sysv/target.mk | 8++++++++
Asrc/cc2/target/i386-sysv/types.c | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rcc2/target/qbe/arch.h -> src/cc2/target/qbe/arch.h | 0
Asrc/cc2/target/qbe/cgen.c | 729+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc2/target/qbe/code.c | 569+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc2/target/qbe/optm.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc2/target/qbe_amd64-sysv/target.mk | 8++++++++
Asrc/cc2/target/qbe_arm64-sysv/target.mk | 5+++++
Rcc2/target/z80-scc/arch.h -> src/cc2/target/z80-scc/arch.h | 0
Asrc/cc2/target/z80-scc/cgen.c | 161+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc2/target/z80-scc/code.c | 229+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cc2/target/z80-scc/optm.c | 11+++++++++++
Asrc/cc2/target/z80-scc/target.mk | 8++++++++
Asrc/cc2/target/z80-scc/types.c | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/driver/Makefile | 8++++++++
Asrc/driver/posix/Makefile | 40++++++++++++++++++++++++++++++++++++++++
Asrc/driver/posix/config.h | 5+++++
Rdriver/posix/config.sh -> src/driver/posix/config.sh | 0
Rdriver/posix/cpp.sh -> src/driver/posix/cpp.sh | 0
Rdriver/posix/deps.mk -> src/driver/posix/deps.mk | 0
Rdriver/posix/scc.c -> src/driver/posix/scc.c | 0
Asrc/ld/Makefile | 21+++++++++++++++++++++
Asrc/ld/coff32.c | 403+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/ld/deps.mk | 15+++++++++++++++
Rld/ld.h -> src/ld/ld.h | 0
Asrc/ld/main.c | 288+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/ld/obj.c | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rlib/c/.gitignore -> src/libc/.gitignore | 0
Asrc/libc/Makefile | 30++++++++++++++++++++++++++++++
Rlib/c/arch/.gitignore -> src/libc/arch/.gitignore | 0
Rlib/c/arch/Makefile -> src/libc/arch/Makefile | 0
Rlib/c/arch/amd64/Makefile -> src/libc/arch/amd64/Makefile | 0
Rlib/c/arch/amd64/dragonfly/.gitignore -> src/libc/arch/amd64/dragonfly/.gitignore | 0
Rlib/c/arch/amd64/dragonfly/Makefile -> src/libc/arch/amd64/dragonfly/Makefile | 0
Rlib/c/arch/amd64/dragonfly/_getheap.s -> src/libc/arch/amd64/dragonfly/_getheap.s | 0
Rlib/c/arch/amd64/dragonfly/_sigaction.c -> src/libc/arch/amd64/dragonfly/_sigaction.c | 0
Rlib/c/arch/amd64/dragonfly/_tzone.c -> src/libc/arch/amd64/dragonfly/_tzone.c | 0
Rlib/c/arch/amd64/dragonfly/gensys.sh -> src/libc/arch/amd64/dragonfly/gensys.sh | 0
Rlib/c/arch/amd64/dragonfly/getenv.c -> src/libc/arch/amd64/dragonfly/getenv.c | 0
Rlib/c/arch/amd64/dragonfly/raise.c -> src/libc/arch/amd64/dragonfly/raise.c | 0
Rlib/c/arch/amd64/dragonfly/signal.c -> src/libc/arch/amd64/dragonfly/signal.c | 0
Rlib/c/arch/amd64/dragonfly/syscall.lst -> src/libc/arch/amd64/dragonfly/syscall.lst | 0
Rlib/c/arch/amd64/dragonfly/time.c -> src/libc/arch/amd64/dragonfly/time.c | 0
Rlib/c/arch/amd64/linux/.gitignore -> src/libc/arch/amd64/linux/.gitignore | 0
Rlib/c/arch/amd64/linux/Makefile -> src/libc/arch/amd64/linux/Makefile | 0
Rlib/c/arch/amd64/linux/_cerrno.s -> src/libc/arch/amd64/linux/_cerrno.s | 0
Rlib/c/arch/amd64/linux/_getheap.s -> src/libc/arch/amd64/linux/_getheap.s | 0
Rlib/c/arch/amd64/linux/_sigaction.c -> src/libc/arch/amd64/linux/_sigaction.c | 0
Rlib/c/arch/amd64/linux/_tzone.c -> src/libc/arch/amd64/linux/_tzone.c | 0
Rlib/c/arch/amd64/linux/errno.lst -> src/libc/arch/amd64/linux/errno.lst | 0
Rlib/c/arch/amd64/linux/gensys.sh -> src/libc/arch/amd64/linux/gensys.sh | 0
Rlib/c/arch/amd64/linux/getenv.c -> src/libc/arch/amd64/linux/getenv.c | 0
Rlib/c/arch/amd64/linux/raise.c -> src/libc/arch/amd64/linux/raise.c | 0
Rlib/c/arch/amd64/linux/signal.c -> src/libc/arch/amd64/linux/signal.c | 0
Rlib/c/arch/amd64/linux/syscall.lst -> src/libc/arch/amd64/linux/syscall.lst | 0
Rlib/c/arch/amd64/linux/time.c -> src/libc/arch/amd64/linux/time.c | 0
Rlib/c/arch/amd64/longjmp.s -> src/libc/arch/amd64/longjmp.s | 0
Rlib/c/arch/amd64/netbsd/.gitignore -> src/libc/arch/amd64/netbsd/.gitignore | 0
Rlib/c/arch/amd64/netbsd/Makefile -> src/libc/arch/amd64/netbsd/Makefile | 0
Rlib/c/arch/amd64/netbsd/_getheap.s -> src/libc/arch/amd64/netbsd/_getheap.s | 0
Rlib/c/arch/amd64/netbsd/_setcontext.s -> src/libc/arch/amd64/netbsd/_setcontext.s | 0
Rlib/c/arch/amd64/netbsd/_sigaction.c -> src/libc/arch/amd64/netbsd/_sigaction.c | 0
Rlib/c/arch/amd64/netbsd/_sigaction2.s -> src/libc/arch/amd64/netbsd/_sigaction2.s | 0
Rlib/c/arch/amd64/netbsd/_tzone.c -> src/libc/arch/amd64/netbsd/_tzone.c | 0
Rlib/c/arch/amd64/netbsd/errno.lst -> src/libc/arch/amd64/netbsd/errno.lst | 0
Rlib/c/arch/amd64/netbsd/gensys.sh -> src/libc/arch/amd64/netbsd/gensys.sh | 0
Rlib/c/arch/amd64/netbsd/getenv.c -> src/libc/arch/amd64/netbsd/getenv.c | 0
Rlib/c/arch/amd64/netbsd/raise.c -> src/libc/arch/amd64/netbsd/raise.c | 0
Rlib/c/arch/amd64/netbsd/signal.c -> src/libc/arch/amd64/netbsd/signal.c | 0
Rlib/c/arch/amd64/netbsd/syscall.lst -> src/libc/arch/amd64/netbsd/syscall.lst | 0
Rlib/c/arch/amd64/netbsd/time.c -> src/libc/arch/amd64/netbsd/time.c | 0
Rlib/c/arch/amd64/openbsd/.gitignore -> src/libc/arch/amd64/openbsd/.gitignore | 0
Rlib/c/arch/amd64/openbsd/Makefile -> src/libc/arch/amd64/openbsd/Makefile | 0
Rlib/c/arch/amd64/openbsd/_getheap.s -> src/libc/arch/amd64/openbsd/_getheap.s | 0
Rlib/c/arch/amd64/openbsd/_sigaction.c -> src/libc/arch/amd64/openbsd/_sigaction.c | 0
Rlib/c/arch/amd64/openbsd/_tzone.c -> src/libc/arch/amd64/openbsd/_tzone.c | 0
Rlib/c/arch/amd64/openbsd/errno.lst -> src/libc/arch/amd64/openbsd/errno.lst | 0
Rlib/c/arch/amd64/openbsd/gensys.sh -> src/libc/arch/amd64/openbsd/gensys.sh | 0
Rlib/c/arch/amd64/openbsd/getenv.c -> src/libc/arch/amd64/openbsd/getenv.c | 0
Rlib/c/arch/amd64/openbsd/raise.c -> src/libc/arch/amd64/openbsd/raise.c | 0
Rlib/c/arch/amd64/openbsd/signal.c -> src/libc/arch/amd64/openbsd/signal.c | 0
Rlib/c/arch/amd64/openbsd/syscall.lst -> src/libc/arch/amd64/openbsd/syscall.lst | 0
Rlib/c/arch/amd64/openbsd/time.c -> src/libc/arch/amd64/openbsd/time.c | 0
Rlib/c/arch/amd64/setjmp.s -> src/libc/arch/amd64/setjmp.s | 0
Rlib/c/arch/arm32/Makefile -> src/libc/arch/arm32/Makefile | 0
Rlib/c/arch/arm32/linux/.gitignore -> src/libc/arch/arm32/linux/.gitignore | 0
Rlib/c/arch/arm32/linux/Makefile -> src/libc/arch/arm32/linux/Makefile | 0
Rlib/c/arch/arm32/linux/_cerrno.s -> src/libc/arch/arm32/linux/_cerrno.s | 0
Rlib/c/arch/arm32/linux/_getheap.s -> src/libc/arch/arm32/linux/_getheap.s | 0
Rlib/c/arch/arm32/linux/_open.c -> src/libc/arch/arm32/linux/_open.c | 0
Rlib/c/arch/arm32/linux/_tzone.c -> src/libc/arch/arm32/linux/_tzone.c | 0
Rlib/c/arch/arm32/linux/gensys.sh -> src/libc/arch/arm32/linux/gensys.sh | 0
Rlib/c/arch/arm32/linux/getenv.c -> src/libc/arch/arm32/linux/getenv.c | 0
Rlib/c/arch/arm32/linux/raise.c -> src/libc/arch/arm32/linux/raise.c | 0
Rlib/c/arch/arm32/linux/signal.c -> src/libc/arch/arm32/linux/signal.c | 0
Rlib/c/arch/arm32/linux/syscall.lst -> src/libc/arch/arm32/linux/syscall.lst | 0
Rlib/c/arch/amd64/dragonfly/time.c -> src/libc/arch/arm32/linux/time.c | 0
Asrc/libc/arch/arm32/longjmp.s | 11+++++++++++
Asrc/libc/arch/arm32/setjmp.s | 9+++++++++
Rlib/c/arch/arm32/Makefile -> src/libc/arch/arm64/Makefile | 0
Rlib/c/arch/arm32/linux/.gitignore -> src/libc/arch/arm64/linux/.gitignore | 0
Rlib/c/arch/arm32/linux/Makefile -> src/libc/arch/arm64/linux/Makefile | 0
Asrc/libc/arch/arm64/linux/_cerrno.s | 13+++++++++++++
Asrc/libc/arch/arm64/linux/_getheap.s | 6++++++
Rlib/c/arch/arm32/linux/_open.c -> src/libc/arch/arm64/linux/_open.c | 0
Rlib/c/arch/amd64/dragonfly/_sigaction.c -> src/libc/arch/arm64/linux/_sigaction.c | 0
Rlib/c/arch/amd64/dragonfly/_tzone.c -> src/libc/arch/arm64/linux/_tzone.c | 0
Asrc/libc/arch/arm64/linux/gensys.sh | 21+++++++++++++++++++++
Rlib/c/arch/amd64/dragonfly/getenv.c -> src/libc/arch/arm64/linux/getenv.c | 0
Rlib/c/arch/amd64/dragonfly/raise.c -> src/libc/arch/arm64/linux/raise.c | 0
Rlib/c/arch/amd64/dragonfly/signal.c -> src/libc/arch/arm64/linux/signal.c | 0
Asrc/libc/arch/arm64/linux/syscall.lst | 11+++++++++++
Rlib/c/arch/amd64/dragonfly/time.c -> src/libc/arch/arm64/linux/time.c | 0
Asrc/libc/arch/arm64/longjmp.s | 22++++++++++++++++++++++
Asrc/libc/arch/arm64/setjmp.s | 20++++++++++++++++++++
Asrc/libc/arch/generrno.sh | 35+++++++++++++++++++++++++++++++++++
Asrc/libc/arch/generrstr.sh | 23+++++++++++++++++++++++
Asrc/libc/arch/mkerrstr | 24++++++++++++++++++++++++
Asrc/libc/arch/posix/_tzone.c | 27+++++++++++++++++++++++++++
Asrc/libc/arch/posix/getenv.c | 18++++++++++++++++++
Asrc/libc/arch/posix/geterrno.sh | 8++++++++
Asrc/libc/arch/posix/raise.c | 11+++++++++++
Asrc/libc/arch/posix/signal.c | 17+++++++++++++++++
Asrc/libc/arch/posix/time.c | 21+++++++++++++++++++++
Asrc/libc/arch/rules.mk | 6++++++
Asrc/libc/assert/Makefile | 10++++++++++
Asrc/libc/assert/__assert.c | 9+++++++++
Asrc/libc/assert/assert.c | 13+++++++++++++
Asrc/libc/ctype/Makefile | 24++++++++++++++++++++++++
Asrc/libc/ctype/ctype.c | 22++++++++++++++++++++++
Asrc/libc/ctype/isalnum.c | 8++++++++
Asrc/libc/ctype/isalpha.c | 8++++++++
Asrc/libc/ctype/isascii.c | 8++++++++
Asrc/libc/ctype/isblank.c | 7+++++++
Asrc/libc/ctype/iscntrl.c | 8++++++++
Asrc/libc/ctype/isdigit.c | 8++++++++
Asrc/libc/ctype/isgraph.c | 8++++++++
Asrc/libc/ctype/islower.c | 8++++++++
Asrc/libc/ctype/isprint.c | 8++++++++
Asrc/libc/ctype/ispunct.c | 8++++++++
Asrc/libc/ctype/isspace.c | 8++++++++
Asrc/libc/ctype/isupper.c | 8++++++++
Asrc/libc/ctype/isxdigit.c | 8++++++++
Asrc/libc/ctype/tolower.c | 9+++++++++
Asrc/libc/ctype/toupper.c | 8++++++++
Asrc/libc/libc.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/locale/Makefile | 10++++++++++
Asrc/libc/locale/localeconv.c | 29+++++++++++++++++++++++++++++
Asrc/libc/locale/setlocale.c | 16++++++++++++++++
Asrc/libc/mklst | 12++++++++++++
Asrc/libc/stdio/Makefile | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/stdio/__getc.c | 39+++++++++++++++++++++++++++++++++++++++
Asrc/libc/stdio/__iob.c | 20++++++++++++++++++++
Asrc/libc/stdio/__putc.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/stdio/_allocbuf.c | 21+++++++++++++++++++++
Asrc/libc/stdio/_flsbuf.c | 23+++++++++++++++++++++++
Asrc/libc/stdio/_fpopen.c | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/stdio/clearerr.c | 8++++++++
Asrc/libc/stdio/fclose.c | 32++++++++++++++++++++++++++++++++
Asrc/libc/stdio/feof.c | 8++++++++
Asrc/libc/stdio/ferror.c | 8++++++++
Asrc/libc/stdio/fgetc.c | 8++++++++
Asrc/libc/stdio/fgets.c | 19+++++++++++++++++++
Asrc/libc/stdio/fopen.c | 23+++++++++++++++++++++++
Asrc/libc/stdio/fprintf.c | 15+++++++++++++++
Asrc/libc/stdio/fputc.c | 8++++++++
Asrc/libc/stdio/fputs.c | 12++++++++++++
Asrc/libc/stdio/fread.c | 25+++++++++++++++++++++++++
Asrc/libc/stdio/freopen.c | 14++++++++++++++
Asrc/libc/stdio/fseek.c | 26++++++++++++++++++++++++++
Asrc/libc/stdio/ftell.c | 27+++++++++++++++++++++++++++
Asrc/libc/stdio/fwrite.c | 24++++++++++++++++++++++++
Asrc/libc/stdio/getc.c | 8++++++++
Asrc/libc/stdio/getchar.c | 8++++++++
Asrc/libc/stdio/gets.c | 17+++++++++++++++++
Asrc/libc/stdio/perror.c | 16++++++++++++++++
Asrc/libc/stdio/printf.c | 15+++++++++++++++
Asrc/libc/stdio/putc.c | 8++++++++
Asrc/libc/stdio/putchar.c | 8++++++++
Asrc/libc/stdio/puts.c | 12++++++++++++
Asrc/libc/stdio/rewind.c | 10++++++++++
Asrc/libc/stdio/setbuf.c | 8++++++++
Asrc/libc/stdio/setvbuf.c | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/stdio/snprintf.c | 16++++++++++++++++
Asrc/libc/stdio/sprintf.c | 16++++++++++++++++
Asrc/libc/stdio/tmpnam.c | 31+++++++++++++++++++++++++++++++
Asrc/libc/stdio/vfprintf.c | 362+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/stdio/vprintf.c | 12++++++++++++
Asrc/libc/stdio/vsnprintf.c | 25+++++++++++++++++++++++++
Asrc/libc/stdio/vsprintf.c | 12++++++++++++
Asrc/libc/stdlib/Makefile | 25+++++++++++++++++++++++++
Asrc/libc/stdlib/abort.c | 10++++++++++
Asrc/libc/stdlib/abs.c | 8++++++++
Asrc/libc/stdlib/atexit.c | 17+++++++++++++++++
Asrc/libc/stdlib/atoi.c | 25+++++++++++++++++++++++++
Asrc/libc/stdlib/atol.c | 26++++++++++++++++++++++++++
Asrc/libc/stdlib/atoll.c | 26++++++++++++++++++++++++++
Asrc/libc/stdlib/bsearch.c | 26++++++++++++++++++++++++++
Asrc/libc/stdlib/calloc.c | 18++++++++++++++++++
Asrc/libc/stdlib/errno.c | 1+
Asrc/libc/stdlib/exit.c | 13+++++++++++++
Asrc/libc/stdlib/labs.c | 8++++++++
Asrc/libc/stdlib/llabs.c | 8++++++++
Asrc/libc/stdlib/malloc.c | 158+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/stdlib/malloc.h | 16++++++++++++++++
Asrc/libc/stdlib/qsort.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/stdlib/rand.c | 18++++++++++++++++++
Asrc/libc/stdlib/realloc.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/stdlib/strtoull.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/string/Makefile | 31+++++++++++++++++++++++++++++++
Asrc/libc/string/memchr.c | 12++++++++++++
Asrc/libc/string/memcmp.c | 14++++++++++++++
Asrc/libc/string/memcpy.c | 13+++++++++++++
Asrc/libc/string/memmove.c | 18++++++++++++++++++
Asrc/libc/string/memset.c | 12++++++++++++
Asrc/libc/string/strcat.c | 14++++++++++++++
Asrc/libc/string/strchr.c | 10++++++++++
Asrc/libc/string/strcmp.c | 10++++++++++
Asrc/libc/string/strcoll.c | 10++++++++++
Asrc/libc/string/strcpy.c | 12++++++++++++
Asrc/libc/string/strcspn.c | 21+++++++++++++++++++++
Asrc/libc/string/strerror.c | 11+++++++++++
Asrc/libc/string/strlen.c | 12++++++++++++
Asrc/libc/string/strncat.c | 15+++++++++++++++
Asrc/libc/string/strncmp.c | 14++++++++++++++
Asrc/libc/string/strncpy.c | 14++++++++++++++
Asrc/libc/string/strnlen.c | 13+++++++++++++
Asrc/libc/string/strpbrk.c | 20++++++++++++++++++++
Asrc/libc/string/strrchr.c | 14++++++++++++++
Asrc/libc/string/strspn.c | 21+++++++++++++++++++++
Asrc/libc/string/strstr.c | 18++++++++++++++++++
Asrc/libc/string/strtok.c | 25+++++++++++++++++++++++++
Asrc/libc/string/strxfrm.c | 12++++++++++++
Asrc/libc/syscall.h | 8++++++++
Asrc/libc/time/Makefile | 16++++++++++++++++
Asrc/libc/time/_daysyear.c | 30++++++++++++++++++++++++++++++
Asrc/libc/time/asctime.c | 12++++++++++++
Asrc/libc/time/ctime.c | 8++++++++
Asrc/libc/time/difftime.c | 8++++++++
Asrc/libc/time/gmtime.c | 36++++++++++++++++++++++++++++++++++++
Asrc/libc/time/localtime.c | 22++++++++++++++++++++++
Asrc/libc/time/mktime.c | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/time/strftime.c | 247+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libcoff32/Makefile | 25+++++++++++++++++++++++++
Asrc/libcoff32/coff32_pack_aout.c | 9+++++++++
Asrc/libcoff32/coff32_pack_ent.c | 20++++++++++++++++++++
Asrc/libcoff32/coff32_pack_hdr.c | 21+++++++++++++++++++++
Asrc/libcoff32/coff32_pack_scn.c | 24++++++++++++++++++++++++
Asrc/libcoff32/coff32_unpack_aout.c | 9+++++++++
Asrc/libcoff32/coff32_unpack_ent.c | 20++++++++++++++++++++
Asrc/libcoff32/coff32_unpack_hdr.c | 22++++++++++++++++++++++
Asrc/libcoff32/coff32_unpack_scn.c | 24++++++++++++++++++++++++
Asrc/libcoff32/deps.mk | 17+++++++++++++++++
Asrc/libcrt/Makefile | 11+++++++++++
Asrc/libcrt/crt-amd64-posix.s | 19+++++++++++++++++++
Asrc/libcrt/crt-arm32-posix.s | 16++++++++++++++++
Asrc/libcrt/crt-arm64-posix.s | 16++++++++++++++++
Asrc/libcrt/crt-dragonfly.s | 1+
Asrc/libcrt/crt-linux.s | 1+
Asrc/libcrt/crt-netbsd.s | 9+++++++++
Asrc/libcrt/crt-openbsd.s | 9+++++++++
Asrc/libscc/Makefile | 31+++++++++++++++++++++++++++++++
Asrc/libscc/alloc.c | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libscc/bpack.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libscc/bunpack.c | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libscc/casecmp.c | 11+++++++++++
Asrc/libscc/debug.c | 20++++++++++++++++++++
Asrc/libscc/deps.mk | 18++++++++++++++++++
Asrc/libscc/die.c | 20++++++++++++++++++++
Asrc/libscc/lpack.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libscc/lunpack.c | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libscc/newitem.c | 12++++++++++++
Asrc/libscc/rmyro.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libscc/wmyro.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libscc/xcalloc.c | 13+++++++++++++
Asrc/libscc/xmalloc.c | 13+++++++++++++
Asrc/libscc/xrealloc.c | 13+++++++++++++
Asrc/libscc/xstrdup.c | 12++++++++++++
Asrc/nm/Makefile | 21+++++++++++++++++++++
Asrc/nm/coff32.c | 312+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/nm/deps.mk | 11+++++++++++
Asrc/nm/formats.c | 13+++++++++++++
Asrc/nm/main.c | 272+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/nm/nm.h | 14++++++++++++++
Asrc/objdump/Makefile | 16++++++++++++++++
Asrc/objdump/deps.mk | 4++++
Asrc/objdump/main.c | 333+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/Makefile | 2+-
828 files changed, 23471 insertions(+), 23623 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,23 +1,6 @@ *.o *.a -root/libexec/scc/cc1-* -root/libexec/scc/cc2-* -root/libexec/scc/as-* -root/bin/ld -root/bin/scc -root/bin/scpp -root/bin/ar -root/bin/nm -root/bin/objdump -test.log -cc2/error.h -instbl.c -config.mk -inc/ldflags.h -inc/sysincludes.h -inc/syslibs.h -inc/syscrts.h -driver/posix/config.h -as/target/*/*tbl.c -*.out -config +bin/ +lib/ +libexec/ +dirs diff --git a/Makefile b/Makefile @@ -1,34 +1,32 @@ -# scc - Suckless C Compiler .POSIX: PROJECTDIR = . +include $(PROJECTDIR)/scripts/rules.mk -include rules.mk +DIRS = src include/scc/scc tests -DIRS = inc cc1 cc2 driver lib as ar nm objdump ld +all: src -all: $(DIRS) +src: dirs include/scc/scc -$(DIRS): config FORCE - +@cd $@ && $(MAKE) all +dirs: $(SCRIPTDIR)/libc-proto + xargs mkdir -p < $(SCRIPTDIR)/libc-proto + touch dirs -clean dep: - $(FORALL) +$(DIRS): FORCE + +@cd $@ && $(MAKE) -distclean: unconfig +dep: $(FORALL) - rm -f config -tests: all - +@cd tests && $(MAKE) -e all +clean: + $(FORALL) + rm -rf lib bin libexec dirs -unconfig: - (echo '/^### Systems/,$$ v/^#/ s/^/#/' ; echo w) | ed -s config.mk - rm -f config +distclean: clean + +@cd include/scc/scc && $(MAKE) distclean -config: - ./config.sh - touch $@ +tests: all install: all mkdir -p $(DESTDIR)$(PREFIX)/ diff --git a/ar/Makefile b/ar/Makefile @@ -1,22 +0,0 @@ -.POSIX: - -PROJECTDIR = .. -include $(PROJECTDIR)/rules.mk -include $(LIBSCC)/libdep.mk - -OBJ = main.o $(DRIVER)/driver.o -MORECFLAGS = -I$(DRIVER) -STDCFLAGS = - -all: $(BINDIR)/ar - -$(BINDIR)/ar: $(OBJ) $(LIBDIR)/libscc.a - $(CC) $(SCC_LDFLAGS) $(OBJ) -lscc -o $@ - -dep: - $(PROJECTDIR)/mkdep.sh - -clean: - rm -f *.o $(DRIVER)/*.o $(BINDIR)/ar - -include deps.mk diff --git a/ar/deps.mk b/ar/deps.mk @@ -1,7 +0,0 @@ -main.o: $(DRIVER)/driver.h - -#deps -main.o: ../inc/ar.h -main.o: ../inc/arg.h -main.o: ../inc/scc.h -posix/driver.o: posix/driver.h diff --git a/ar/main.c b/ar/main.c @@ -1,643 +0,0 @@ -static char sccsid[] = "@(#) ./ar/main.c"; - -#include <errno.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#include <driver.h> - -#include "../inc/ar.h" -#include "../inc/arg.h" -#include "../inc/scc.h" - -enum { - BEFORE, - INDOT, - AFTER, -}; - -struct tmp { - char *name; - FILE *fp; -} tmps[3]; - -char *argv0; - -static int bflag, vflag, cflag, lflag, uflag, aflag; -static char *arfile, *posname; - -struct member { - FILE *src; - struct ar_hdr hdr; - int cur; - char *fname; - long size; - long mode; - long long date; -}; - -static void -cleanup(void) -{ - int i; - - for (i = 0; i < 3; i++) { - if (tmps[i].name) - remove(tmps[i].name); - } -} - -/* - * I do know that you cannot call remove from a signal handler - * but we only can use stdio function to deal with files - * because we are C99 compliant, and it is very likely that - * remove is going to work in this case - */ -static void -sigfun(int signum) -{ - cleanup(); - _Exit(1); -} - -static FILE * -openar(void) -{ - FILE *fp; - char magic[SARMAG+1]; - - if ((fp = fopen(arfile,"r+b")) == NULL) { - if (!cflag) - fprintf(stderr, "ar: creating %s\n", arfile); - if ((fp = fopen(arfile, "w+b")) == NULL) { - perror("ar:opening archive"); - exit(1); - } - fputs(ARMAG, fp); - if (fflush(fp) == EOF) { - perror("ar:writing magic number"); - exit(1); - } - } else { - if (fgets(magic, sizeof(magic), fp) == NULL) { - perror("ar:error reading magic number"); - exit(1); - } - if (strcmp(magic, ARMAG)) { - fprintf(stderr, - "ar:%s:invalid magic number '%s'\n", - arfile, - magic); - exit(1); - } - } - return fp; -} - -static void -archive(char *fname, FILE *to, char letter) -{ - int c; - size_t n; - FILE *from; - char mtime[13]; - struct stat st; - - if (vflag) - printf("%c - %s\n", letter, fname); - if (strlen(fname) > 16) - fprintf(stderr, "ar:%s: too long name\n", fname); - if ((from = fopen(fname, "rb")) == NULL) { - fprintf(stderr, - "ar:opening member '%s':%s\n", - fname, - strerror(errno)); - exit(1); - } - if (stat(fname, &st) < 0) { - fprintf(stderr, "ar:error getting '%s' attributes\n", fname); - exit(1); - } - strftime(mtime, sizeof(mtime), "%s", gmtime(&st.st_mtime)); - fprintf(to, - "%-16.16s%-12s%-6u%-6u%-8o%-10llu`\n", - fname, - mtime, - st.st_uid, - st.st_gid, - st.st_mode, - (unsigned long long) st.st_size); - for (n = 0; (c = getc(from)) != EOF; n++) - putc(c, to); - if (n & 1) - putc('\n', to); - if (ferror(from)) { - fprintf(stderr, - "ar:reading input '%s':%s\n", - fname, strerror(errno)); - exit(1); - } - fclose(from); -} - -static void -append(FILE *fp, char *argv[]) -{ - char *fname; - - if (fseek(fp, 0, SEEK_END) == EOF) { - perror("ar:seeking archive"); - exit(1); - } - - for ( ; fname = *argv; ++argv) { - *argv = NULL; - archive(fname, fp, 'a'); - } - - if (fclose(fp) == EOF) { - perror("ar:error writing archive"); - exit(1); - } -} - -static void -copy(struct member *m, struct tmp *tmp) -{ - int c; - size_t siz = m->size; - struct ar_hdr *hdr = &m->hdr; - - fwrite(hdr, sizeof(*hdr), 1, tmp->fp); - if ((siz & 1) == 1) - siz++; - while (siz--) { - if ((c = getc(m->src)) == EOF) - break; - fputc(c, tmp->fp); - } -} - -static void -letters(unsigned long val, char *s) -{ - *s++ = (val & 04) ? 'r' : '-'; - *s++ = (val & 02) ? 'w' : '-'; - *s++ = (val & 01) ? 'x' : '-'; -} - -static char * -perms(struct member *m) -{ - static char buf[10]; - - letters(m->mode >> 6, buf); - letters(m->mode >> 3, buf+3); - letters(m->mode, buf +6); - buf[9] = '\0'; - - return buf; -} - -static int -inlist(char *fname, int argc, char *argv[]) -{ - for (; argc-- > 0; ++argv) { - if (*argv && !strcmp(*argv, fname)) { - *argv = NULL; - return 1; - } - } - return 0; -} - -static void -move(struct member *m, int argc, char *argv[]) -{ - int where; - - if (inlist(m->fname, argc, argv)) { - if (vflag) - printf("m - %s\n", m->fname); - where = INDOT; - } else if (posname && !strcmp(posname, m->fname)) { - where = (bflag) ? AFTER : BEFORE; - m->cur = AFTER; - } else { - where = m->cur; - } - copy(m, &tmps[where]); -} - -static void -insert(int argc, char *argv[]) -{ - for (; argc-- > 0; ++argv) { - if (*argv) { - archive(*argv, tmps[INDOT].fp, 'a'); - *argv = NULL; - } - } -} - -static void -update(struct member *m, int argc, char *argv[]) -{ - int where; - FILE *fp = tmps[BEFORE].fp; - - if (inlist(m->fname, argc, argv)) { - archive(m->fname, tmps[m->cur].fp, 'r'); - return; - } else if (posname && !strcmp(posname, m->fname)) { - where = (bflag) ? AFTER : BEFORE; - m->cur = AFTER; - } else { - where = m->cur; - } - copy(m, &tmps[where]); -} - -static void -extract(struct member *m, int argc, char *argv[]) -{ - int c; - long siz; - FILE *fp; - - if (argc > 0 && !inlist(m->fname, argc, argv)) - return; - if (vflag) - printf("x - %s\n", m->fname); - siz = m->size; - - if ((fp = fopen(m->fname, "wb")) == NULL) - goto error_file; - while (siz-- > 0 && (c = getc(m->src)) != EOF) - putc(c, fp); - fflush(fp); - if (fclose(fp) == EOF) - goto error_file; - - /* TODO: set attributes */ - return; - - -error_file: - perror("ar:error extracting file"); - exit(1); -} - -static void -print(struct member *m, int argc, char *argv[]) -{ - long siz; - int c; - - if (argc > 0 && !inlist(m->fname, argc, argv)) - return; - if (vflag) - printf("\n<%s>\n\n", m->fname); - siz = m->size; - while (siz-- > 0 && (c = getc(m->src)) != EOF) - putchar(c); -} - -static void -list(struct member *m, int argc, char *argv[]) -{ - time_t t; - struct ar_hdr *hdr = &m->hdr; - char mtime[30]; - - if (argc > 0 && !inlist(m->fname, argc, argv)) - return; - if (!vflag) { - printf("%s\n", m->fname); - } else { - t = totime(m->date); - strftime(mtime, sizeof(mtime), "%c", localtime(&t)); - printf("%s %ld/%ld\t%s %s\n", - perms(m), - atol(hdr->ar_uid), - atol(hdr->ar_gid), - mtime, - m->fname); - } -} - -static void -del(struct member *m, int argc, char *argv[]) -{ - if (inlist(m->fname, argc, argv)) { - if (vflag) - printf("d - %s\n", m->fname); - return; - } - copy(m, &tmps[BEFORE]); -} - -static char * -getfname(struct ar_hdr *hdr) -{ - static char fname[SARNAM+1]; - size_t i; - - memcpy(fname, hdr->ar_name, SARNAM); - fname[SARNAM] = '\0'; - - for (i = SARNAM-1; i >= 0; --i) { - if (fname[i] != ' ' && fname[i] != '/') - break; - fname[i] = '\0'; - } - return fname; -} - -static long long -getnum(char *s, int size, int base) -{ - int c; - long long val; - char *p; - static char digits[] = "0123456789"; - - for (val = 0; size > 0; val += c) { - --size; - if ((c = *s++) == ' ') - break; - if ((p = strchr(digits, c)) == NULL) - return -1; - if ((c = p - digits) >= base) - return -1; - val *= base; - } - - while (size > 0 && *s++ == ' ') - --size; - return (size == 0) ? val : -1; -} - -static int -valid(struct member *m) -{ - struct ar_hdr *hdr = &m->hdr; - - m->fname = getfname(&m->hdr); - m->size = getnum(hdr->ar_size, sizeof(hdr->ar_size), 10); - m->mode = getnum(hdr->ar_mode, sizeof(hdr->ar_mode), 8); - m->date = getnum(hdr->ar_date, sizeof(hdr->ar_date), 10); - - if (strncmp(hdr->ar_fmag, ARFMAG, sizeof(hdr->ar_fmag)) || - m->size < 0 || m->mode < 0 || m->date < 0) { - return 0; - } - return 1; -} - -static void -run(FILE *fp, int argc, char *argv[], - void (*fun)(struct member *, int argc, char *files[])) -{ - struct member m; - - m.src = fp; - m.cur = BEFORE; - - while (fread(&m.hdr, sizeof(m.hdr), 1, fp) == 1) { - fpos_t pos; - - if (!valid(&m)) { - fprintf(stderr, - "ar:corrupted member '%s'\n", - m.fname); - exit(1); - } - fgetpos(fp, &pos); - (*fun)(&m, argc, argv); - fsetpos(fp, &pos); - fseek(fp, m.size+1 & ~1, SEEK_CUR); - } - if (ferror(fp) || fclose(fp) == EOF) { - perror("ar:reading members"); - exit(1); - } -} - -static void -merge(void) -{ - FILE *fp, *fi; - int c, i; - - - if ((fp = fopen(arfile, "wb")) == NULL) { - perror("ar:reopening archive"); - exit(1); - } - - fputs(ARMAG, fp); - - for (i = 0; i < 3; i++) { - if ((fi = tmps[i].fp) == NULL) - continue; - fseek(fi, 0, SEEK_SET); - while ((c = getc(fi)) != EOF) - putc(c, fp); - if (ferror(fi)) { - perror("ar:error in temporary"); - exit(1); - } - } - - if (fclose(fp) == EOF) { - perror("ar:writing archive file"); - exit(1); - } -} - -static void -closetmp(int which) -{ - struct tmp *tmp = &tmps[which]; - - if (!tmp->fp) - return; - if (fclose(tmp->fp) == EOF) { - perror("ar:closing temporaries"); - exit(1); - } -} - -static void -opentmp(char *fname, int which) -{ - struct tmp *tmp = &tmps[which]; - - if (lflag) { - tmp->name = fname; - tmp->fp = fopen(fname, "w+b"); - } else { - tmp->fp = tmpfile(); - } - - if (tmp->fp == NULL) { - perror("ar:creating temporary"); - exit(1); - } -} - -static void -doit(int key, char *argv[], int argc) -{ - FILE *fp; - - fp = openar(); - if (argc == 0 && - (key == 'r' || key == 'd' || key == 'm' || key == 'q')) { - if (fclose(fp) == EOF) { - perror("ar:early close of archive file"); - exit(-1); - } - return; - } - - if (key == 'r' || key == 'm' || key == 'd') - opentmp("ar.tmp1", BEFORE); - if (key == 'r' || key == 'm') { - opentmp("ar.tmp2", INDOT); - opentmp("ar.tmp3", AFTER); - } - - switch (key) { - case 'r': - run(fp, argc, argv, update); - insert(argc, argv); - merge(); - break; - case 'm': - run(fp, argc, argv, move); - merge(); - break; - case 'd': - run(fp, argc, argv, del); - merge(); - break; - case 't': - run(fp, argc, argv, list); - break; - case 'p': - run(fp, argc, argv, print); - break; - case 'x': - run(fp, argc, argv, extract); - break; - case 'q': - append(fp, argv); - break; - } - - closetmp(BEFORE); - closetmp(INDOT); - closetmp(AFTER); - - for ( ; argc-- > 0; ++argv) { - if (*argv) { - fprintf(stderr, "ar: No member named '%s'\n", *argv); - exit(1); - } - } -} - -static void -usage(void) -{ - fputs("ar [-drqtpmx][posname] [-vuaibcl] [posname] arfile name ...\n", - stderr); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - int key, nkey = 0, pos = 0; - - atexit(cleanup); - ARGBEGIN { - case 'd': - nkey++; - key = 'd'; - break; - case 'r': - nkey++; - key = 'r'; - break; - case 'q': - nkey++; - key = 'q'; - break; - case 't': - nkey++; - key = 't'; - break; - case 'p': - nkey++; - key = 'p'; - break; - case 'm': - nkey++; - key = 'm'; - break; - case 'x': - nkey++; - key = 'x'; - break; - case 'a': - aflag = 1; - pos++; - posname = EARGF(usage()); - break; - case 'i': - case 'b': - bflag = 1; - pos++; - posname = EARGF(usage()); - break; - case 'v': - vflag = 1; - break; - case 'c': - cflag = 1; - break; - case 'l': - lflag = 1; - break; - case 'u': - /* TODO */ - abort(); - uflag = 1; - break; - default: - usage(); - } ARGEND - - if (nkey == 0 || nkey > 1 || pos > 1 || argc == 0) - usage(); - - signal(SIGINT, sigfun); - signal(SIGQUIT, sigfun); - signal(SIGTERM, sigfun); - - arfile = *argv; - doit(key, ++argv, --argc); - - if (fflush(stdout) == EOF) { - perror("ar:error writing to stdout"); - exit(1); - } - - return 0; -} diff --git a/as/Makefile b/as/Makefile @@ -1,29 +0,0 @@ -.POSIX: - -PROJECTDIR = .. -include $(PROJECTDIR)/rules.mk -include $(LIBSCC)/libdep.mk - -OBJ = main.o symbol.o ins.o parser.o expr.o myro.o -MORECFLAGS = -I$(INCLUDE)/$(STD) -TARGETS = $(LIBEXEC)/as-amd64 $(LIBEXEC)/as-i386 \ - $(LIBEXEC)/as-i286 $(LIBEXEC)/as-z80 - -all: $(TARGETS) - -$(TARGETS): $(LIBDIR)/libscc.a - -dep: - $(PROJECTDIR)/mkdep.sh - -clean: - rm -f *.o target/*/*.o - rm -f target/*/*tbl.c - rm -f as-* - rm -f $(TARGETS) - -include target/amd64.mk -include target/i386.mk -include target/i286.mk -include target/z80.mk -include deps.mk diff --git a/as/deps.mk b/as/deps.mk @@ -1,46 +0,0 @@ -parser.o: $(PROJECTDIR)/inc/$(STD)/cstd.h - -#deps -expr.o: ../inc/scc.h -expr.o: as.h -ins.o: ../inc/scc.h -ins.o: as.h -main.o: ../inc/arg.h -main.o: ../inc/scc.h -main.o: as.h -myro.o: ../inc/myro.h -myro.o: ../inc/scc.h -myro.o: as.h -parser.o: ../inc/scc.h -parser.o: as.h -symbol.o: ../inc/scc.h -symbol.o: as.h -target/x80/ins.o: target/x80/../../../inc/scc.h -target/x80/ins.o: target/x80/../../as.h -target/x80/ins.o: target/x80/proc.h -target/x80/z80.o: target/x80/../../../inc/scc.h -target/x80/z80.o: target/x80/../../as.h -target/x80/z80.o: target/x80/../x80/proc.h -target/x80/z80tbl.o: target/x80/../../../inc/scc.h -target/x80/z80tbl.o: target/x80/../../as.h -target/x80/z80tbl.o: target/x80/../x80/proc.h -target/x86/amd64.o: target/x86/../../../inc/scc.h -target/x86/amd64.o: target/x86/../../as.h -target/x86/amd64tbl.o: target/x86/../../../inc/scc.h -target/x86/amd64tbl.o: target/x86/../../as.h -target/x86/amd64tbl.o: target/x86/../x86/proc.h -target/x86/i286.o: target/x86/../../../inc/scc.h -target/x86/i286.o: target/x86/../../as.h -target/x86/i286.o: target/x86/../x86/proc.h -target/x86/i286tbl.o: target/x86/../../../inc/scc.h -target/x86/i286tbl.o: target/x86/../../as.h -target/x86/i286tbl.o: target/x86/../x86/proc.h -target/x86/i386.o: target/x86/../../../inc/scc.h -target/x86/i386.o: target/x86/../../as.h -target/x86/i386.o: target/x86/../x86/proc.h -target/x86/i386tbl.o: target/x86/../../../inc/scc.h -target/x86/i386tbl.o: target/x86/../../as.h -target/x86/i386tbl.o: target/x86/../x86/proc.h -target/x86/ins.o: target/x86/../../../inc/scc.h -target/x86/ins.o: target/x86/../../as.h -target/x86/ins.o: target/x86/proc.h diff --git a/as/expr.c b/as/expr.c @@ -1,303 +0,0 @@ -static char sccsid[] = "@(#) ./as/expr.c"; - -#include <ctype.h> -#include <stdlib.h> -#include <string.h> - -#include "../inc/scc.h" -#include "as.h" - -#define NNODES 10 - -static Alloc *arena; - -Node * -node(int op, Node *l, Node *r) -{ - struct arena *ap; - Node *np; - - if (!arena) - arena = alloc(sizeof(Node), NNODES); - np = new(arena); - np->op = op; - np->left = l; - np->right = r; - np->sym = NULL; - - return np; -} - -void -deltree(Node *np) -{ - if (!np) - return; - deltree(np->left); - deltree(np->right); - delete(arena, np); -} - -static Node * -fold(int op, Node *l, Node *r) -{ - Node *np; - TUINT val, lv, rv; - - lv = l->sym->value; - rv = r->sym->value; - - /* TODO: check overflow */ - - switch (op) { - case '*': - val = lv - rv; - break; - case '/': - if (rv == 0) - goto division_by_zero; - val = lv / rv; - break; - case '%': - if (rv == 0) - goto division_by_zero; - val = lv % rv; - break; - case SHL: - val = lv << rv; - break; - case SHR: - val = lv >> rv; - break; - case '+': - val = lv + rv; - break; - case '-': - val = lv - rv; - break; - case '<': - val = lv < rv; - break; - case '>': - val = lv > rv; - break; - case '=': - val = lv == rv; - break; - case GE: - val = lv >= rv; - break; - case LE: - val = lv <= rv; - break; - case '|': - val = lv | rv; - break; - case '^': - val = lv ^ rv; - break; - default: - abort(); - } - deltree(l); - deltree(r); - - np = node(NUMBER, NULL, NULL); - np->sym = tmpsym(val); - np->addr = ANUMBER; - return np; - -division_by_zero: - error("division by 0"); -} - -static Node * -binary(int op, Node *l, Node *r) -{ - int addr; - Node *np; - - if (l->op == NUMBER && r->op == NUMBER) - return fold(op, l, r); - else - abort(); - np = node(op, l, r); - np->addr = addr; - - return np; -} - -static Node * -unaryop(int op, Node *np) -{ - TUINT val; - - if (np->addr != ANUMBER) - error("invalid argument for unary operator"); - if (np->op != NUMBER) { - np = node(op, np, NULL); - np->addr = ANUMBER; - return np; - } - - val = np->sym->value; - switch (op) { - case '!': - val = !val; - case '+': - break; - case '-': - val = -val; - break; - default: - abort(); - } - np->sym->value = val; - - return np; -} - -/*************************************************************************/ -/* grammar functions */ -/*************************************************************************/ - -static Node * -primary(void) -{ - Node *np; - - switch (yytoken) { - case IDEN: - case NUMBER: - np = node(yytoken, NULL, NULL); - np->sym = yylval.sym; - np->addr = ANUMBER; - next(); - break; - case '(': - np = expr(); - expect(')'); - break; - default: - unexpected(); - } - - return np; -} - -static Node * -unary(void) -{ - int op, tok; - Node *np; - - switch (tok = yytoken) { - case '!': - case '-': - case '+': - next(); - return unaryop(tok, primary()); - default: - return primary(); - } -} - -static Node * -mul(void) -{ - int op; - Node *np; - - np = unary(); - for (;;) { - switch (op = yytoken) { - case '*': - case '/': - case '%': - case SHL: - case SHR: - next(); - binary(op, np, primary()); - break; - default: - return np; - } - } -} - -static Node * -add(void) -{ - int op; - Node *np; - - np = mul(); - for (;;) { - switch (op = yytoken) { - case '+': - case '-': - next(); - np = binary(op, np, mul()); - break; - default: - return np; - } - } -} - -static Node * -relational(void) -{ - int op; - Node *np; - - np = add(); - for (;;) { - switch (op = yytoken) { - case '<': - case '>': - case '=': - case GE: - case LE: - next(); - np = binary(op, np, add()); - break; - default: - return np; - } - } -} - -static Node * -and(void) -{ - int op; - Node *np; - - np = relational(); - while (accept('&')) - np = binary('&', np, relational()); - return np; -} - -Node * -expr(void) -{ - int op; - Node *np; - - regctx(0); - np = and(); - for (;;) { - switch (op = yytoken) { - case '|': - case '^': - next(); - np = binary(op, np, and()); - break; - default: - regctx(1); - return np; - } - } -} diff --git a/as/gentbl.awk b/as/gentbl.awk @@ -1,112 +0,0 @@ - -BEGIN { - printf "#include \"../../../inc/scc.h\"\n"\ - "#include \"../../as.h\"\n"\ - "#include \"../" family "/proc.h\"\n" - - rules = "target/" family "/rules.dat" - while (getline < rules > 0) { - regex[++nregs] = $1 - value[nregs] = $2 - } - close(rules) -} - {sub(/#.*/,"")} - -$7 !~ cpu {next} - -/^$/ {next} - - { - if (opstart[$1] == 0) { - opstart[$1] = nvar - opnames[nop++] = $1 - } - opcount[$1]++ - opargs[nvar] = $3 - opsize[nvar] = $4 - opbytes[nvar] = ($5 == "none") ? "" : $5 - opformat[nvar++] = $6 - formats[$6] = 1 -} - -END { - for (i in formats) - printf "Format %s;\n", i - - printf "int nr_ins = %d;\n\n", nop - print "struct ins instab[] = {" - for (i = 0; i < nop; i++) { - n = opnames[i] - start = opstart[n] - end = start + opcount[n] - printf "\t{.str = \"%s\", .begin = %d, .end = %d},\n", - n, start, end | "sort" - } - close("sort") - printf "};\n\n" - - print "struct op optab[] = {" - for (i = 0; i < nvar; i++) { - printf "\t/* %d */\n", i - printf "\t{\n" \ - "\t\t.size = %d,\n"\ - "\t\t.format = %s,\n", - opsize[i], opformat[i] - - if (opbytes[i] != "") - printf "\t\t.bytes = (unsigned char [%d]) {%s},\n", - opsize[i], - opbytes[i] - - a = str2args(opargs[i]) - if (a != "") - printf "\t\t.args = (unsigned char []) {%s}\n", a - - print "\t}," - } - print "};" -} - -function str2args(s, args, i, j, out, n, found) -{ - n = split(s, args, /,/) - if (n == 0 || args[1] == "none") - return "" - for (i = 1; i <= n; i++) { - a = args[i] - found = 0 - - if (a ~ /\?$/) - out = out "AOPT ," - else if (a ~ /\+$/) - out = out "AREP ," - - for (j = 1; j <= nregs; j++) { - if (match(a, "^" regex[j])) { - out = out value[j] - found = 1 - break - } - } - - if (!found) { - print FILENAME ":" NR ":" \ - $0 ":wrong arg", a > "/dev/stderr" - exit 1 - } - - a = substr(a, RLENGTH+1) - sub(/\?$/, "", a) - sub(/\+$/, "", a) - if (a != "") { - print FILENAME ":" NR ":" \ - $0 ": trailing chars: ", a > "/dev/stderr" - exit 1 - } - out = out "," - } - out = out "0" - - return out -} diff --git a/as/gentbl.sh b/as/gentbl.sh @@ -1,33 +0,0 @@ -#!/bin/sh - - -set -e - -while test $# -gt 0 -do - case $1 in - -c) - cpu=$2 - shift - ;; - -f) - family=$2 - shift - ;; - *) - echo gen.sh:incorrect parameter:$1 >&2 - exit 1 - ;; - esac - shift -done - -echo cpu=${cpu:=z80} family=${family:=x80} - -rm -f $$.c target/$family/${cpu}tbl.c -trap "rm -f $$.c" 0 2 3 - -awk '!/^$/ {print $1,NR,$2,$3,$4,$5,$6}' target/$family/$family.dat | -LC_COLLATE=C sort -k1 -k2n | -awk -v cpu=`echo $cpu | tr a-z A-Z` -v family=$family -f gentbl.awk > $$.c && -mv $$.c target/$family/${cpu}tbl.c diff --git a/as/ins.c b/as/ins.c @@ -1,249 +0,0 @@ -static char sccsid[] = "@(#) ./as/ins.c"; - -#include <string.h> - -#include "../inc/scc.h" -#include "as.h" - -extern Section *sabs, *sbss, *sdata, *stext; - -enum { - EQU, - COMMON, - SIZE, - XSTRING, - ASCII, - TYPE, -}; - -char * -tobytes(TUINT v, int nbytes, int inc) -{ - static char buf[sizeof(TUINT)]; - int idx; - - idx = (inc < 0) ? nbytes-1 : 0; - while (nbytes--) { - buf[idx] = v; - idx += inc; - v >>= 8; - } - - if (v) - error("overflow in immediate value"); - return buf; -} - -void -noargs(Op *op, Node **args) -{ - emit(op->bytes, op->size); -} - -static void -xstring(int which, Node **args) -{ - Node *np; - char *s; - size_t len; - - while (np = *args++) { - s = np->sym->name.buf; - len = strlen(s); - len += which == XSTRING; - emit(s, len); - } -} - -void -string(Op *op, Node **args) -{ - xstring(STRING, args); -} - -void -ascii(Op *op, Node **args) -{ - xstring(STRING, args); -} - -void -def(Node **args, int siz) -{ - Node *np; - - while (np = *args++) { - Symbol *sym = np->sym; - - if ((sym->flags & FABS) == 0) - reloc(sym, 0, siz, siz * 8, 0); - emit(tobytes(sym->value, siz, endian), siz); - } -} - -void -defb(Op *op, Node **args) -{ - def(args, 1); -} - -void -defw(Op *op, Node **args) -{ - def(args, 2); -} - -void -defd(Op *op, Node **args) -{ - def(args, 4); -} - -void -defq(Op *op, Node **args) -{ - def(args, 8); -} - -static void -symexp(int which, Op *op, Node **args) -{ - Symbol *sym, *exp; - static char *cmds[] = { - [EQU] = "equ", - [COMMON] = "common", - [SIZE] = "size", - }; - char *cmd = cmds[which]; - - if (args[1]) { - sym = args[0]->sym; - exp = args[1]->sym; - } else if (linesym) { - sym = linesym; - exp = args[0]->sym; - } else { - error("%s pseudo instruction lacks a label", cmd); - } - - if ((exp->flags & FABS) == 0) - error("%s expression is not an absolute expression", cmd); - - switch (which) { - case EQU: - if (pass == 1 && (sym->flags & FDEF)) - error("redefinition of symbol '%s'", sym->name.buf); - sym->value = exp->value; - sym->flags |= FDEF; - break; - case COMMON: - sym->flags |= FCOMMON; - case SIZE: - sym->size = exp->value; - break; - case TYPE: - sym->type.buf = xstrdup(exp->name.buf); - break; - } -} - -void -equ(Op *op, Node **args) -{ - symexp(EQU, op, args); -} - -void -common(Op *op, Node **args) -{ - symexp(COMMON, op, args); -} - -void -size(Op *op, Node **args) -{ - symexp(SIZE, op, args); -} - -void -type(Op *op, Node **args) -{ - symexp(TYPE, op, args); -} - -void -section(Op *op, Node **args) -{ - Symbol *sym = args[0]->sym; - char *attr = NULL; - - if (args[1]) - attr = args[1]->sym->name.buf; - - setsec(sym->name.buf, attr); -} - -void -text(Op *op, Node **args) -{ - cursec = stext; -} - -void -data(Op *op, Node **args) -{ - cursec = sdata; -} - -void -bss(Op *op, Node **args) -{ - cursec = sbss; -} - -void -extrn(Op *op, Node **args) -{ - Symbol *sym = args[0]->sym; - - sym->flags |= FEXTERN; -} - -void -global(Op *op, Node **args) -{ - Symbol *sym = args[0]->sym; - - sym->flags |= FGLOBAL; -} - -void -align(Op *op, Node **args) -{ - Symbol *sym = args[0]->sym; - TUINT curpc, pc, al; - - if ((sym->flags & FABS) == 0) - error("align expression is not an absolute expression"); - if ((al = sym->value) == 0) - return; - - al--; - curpc = cursec->curpc; - pc = curpc+al & ~al; - - for (al = pc - curpc; al > 0; --al) - emit((char []) {0}, 1); -} - -void -end(Op *op, Node **args) -{ - endpass = 1; -} - -void -include(Op *op, Node **args) -{ - addinput(args[0]->sym->name.buf); -} diff --git a/as/main.c b/as/main.c @@ -1,138 +0,0 @@ -static char sccsid[] = "@(#) ./as/main.c"; - -#include <ctype.h> -#include <setjmp.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "../inc/scc.h" -#include "../inc/arg.h" -#include "as.h" - -char *argv0; -char *outfile, *infile; -int endpass; - - -static void -cleanup(void) -{ - if (outfile) - remove(outfile); -} - -static int -cmp(const void *f1, const void *f2) -{ - const Ins *ins = f2; - const char *s = f1; - int d; - - if ((d = *s - *ins->str) != 0) - return d; - - return strcmp(s, ins->str); -} - -static void -as(char *text, char *xargs) -{ - int c; - char *p; - Ins *ins; - Op *op, *lim; - Node **args; - - for (p = text; c = *p; ++p) - *p = toupper(c); - - ins = bsearch(text, instab, nr_ins, sizeof(Ins), cmp); - if (!ins) { - error("invalid instruction '%s'", text); - return; - } - - args = getargs(xargs); - lim = &optab[ins->end]; - for (op = &optab[ins->begin]; op < lim; ++op) { - if (match(op, args)) - break; - } - if (op == lim) { - error("invalid operands for '%s'", text); - return; - } - (*op->format)(op, args); -} - -static int -dopass(char *fname) -{ - struct line line; - FILE *fp; - extern int nerrors; - extern jmp_buf recover; - - addinput(fname); - cleansecs(); - - endpass = 0; - setjmp(recover); - while (!endpass && nextline(fp, &line)) { - linesym = NULL; - - if (line.label) - linesym = deflabel(line.label); - - if (line.op) - as(line.op, line.args); - else if (line.args) - error("arguments without an opcode"); - } - - return nerrors == 0; -} - -static void -usage(void) -{ - fputs("usage: as [-o outfile] filename ...\n", stderr); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - char **p; - - outfile = "a.out"; - - ARGBEGIN { - case 'o': - outfile = EARGF(usage()); - break; - default: - usage(); - } ARGEND - - if (argc == 0) - usage(); - - atexit(cleanup); - iarch(); - isecs(); - - for (pass = 1; pass <= 2; pass++) { - for (p = argv; infile = *p; ++p) { - if (!dopass(infile)) - return 1; - } - if (pass == 1) - killtmp(); - } - writeout(outfile); - outfile = NULL; - - return 0; -} diff --git a/as/myro.c b/as/myro.c @@ -1,204 +0,0 @@ -static char sccsid[] = "@(#) ./as/myro.c"; - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "../inc/scc.h" -#include "../inc/myro.h" -#include "as.h" - -#define FORMAT "z80-scc" - -static Reloc *relocs; -static size_t relcap, relsiz; - -static size_t -writestrings(FILE *fp) -{ - int type; - size_t off = 0; - size_t len; - Symbol *sym; - Section *sp; - String *str; - - fwrite(FORMAT, sizeof(FORMAT), 1, fp); - off = sizeof(FORMAT); - - for (sym = symlist; sym; sym = sym->next) { - if (sym->flags & FREG) - continue; - str = &sym->name; - len = strlen(str->buf) + 1; - fwrite(str->buf, len, 1, fp); - str->offset = off; - off += len; - } - - return off; -} - -static unsigned -getsecflags(Section *sp) -{ - unsigned flags = 0; - - if (sp->flags & SREAD) - flags |= MYROSEC_READ; - if (sp->flags & SWRITE) - flags |= MYROSEC_WRITE; - if (sp->flags & SFILE) - flags |= MYROSEC_FILE; - if (sp->flags & SEXEC) - flags |= MYROSEC_EXEC; - if (sp->flags & SLOAD) - flags |= MYROSEC_LOAD; - if (sp->flags & SABS) - flags |= MYROSEC_ABS; - return flags; -} - -static size_t -writesections(FILE *fp) -{ - Section *sp; - size_t off = 0; - struct myrosect sect; - unsigned id = 0;; - - for (sp = seclist; sp; sp = sp->next) { - if (id == MYROMAXSEC) - die("too many sections for a myro file"); - sp->id = id++; - sect.name = sp->sym->name.offset; - sect.flags = getsecflags(sp); - sect.fill = sp->fill; - sect.aligment = sp->aligment; - sect.offset = off; - sect.len = sp->max - sp->base; - off += wrmyrosec(fp, &sect); - } - - return off; -} - -static unsigned -getsymflags(Symbol *sym) -{ - unsigned flags = 0; - - if (sym->flags & FCOMMON) - flags |= MYROSYM_COMMON; - if (sym->flags & FEXTERN) - flags |= MYROSYM_EXTERN; - if (!(sym->flags & FDEF)) - flags |= MYROSYM_UNDEF; - return flags; -} - -static size_t -writesymbols(FILE *fp) -{ - Symbol *sym; - size_t off = 0; - struct myrosym symbol; - - for (sym = symlist; sym; sym = sym->next) { - if (sym->flags & (FREG|FSECT)) - continue; - symbol.name = sym->name.offset; - symbol.type = -1; - symbol.section = sym->section->id; - symbol.flags = getsymflags(sym); - symbol.offset = sym->value; - symbol.len = sym->size; - off += wrmyrosym(fp, &symbol); - } - - return off; -} - -static size_t -writerelocs(FILE *fp) -{ - Reloc *bp, *lim; - size_t off = 0; - struct myrorel reloc; - - lim = &relocs[relsiz]; - for (bp = relocs; bp < lim; ++bp) { - reloc.id = 0; - reloc.flags = bp->flags; - reloc.size = bp->size; - reloc.nbits = bp->nbits; - reloc.shift = bp->shift; - reloc.offset = bp->offset; - off += wrmyrorel(fp, &reloc); - } - return off; -} - -static void -writedata(FILE *fp) -{ - Section *sp; - - for (sp = seclist; sp; sp = sp->next) { - if (!sp->mem) - continue; - fwrite(sp->mem, sp->max - sp->base, 1, fp); - } -} - -void -writeout(char *name) -{ - FILE *fp; - struct myrohdr hdr = { .magic = MYROMAGIC }; - - if ((fp = fopen(name, "wb")) == NULL) - die("error opening output file '%s'\n", name); - - wrmyrohdr(fp, &hdr); - hdr.strsize = writestrings(fp); - hdr.secsize = writesections(fp); - hdr.symsize = writesymbols(fp); - hdr.relsize = writerelocs(fp); - writedata(fp); - - fseek(fp, 0, SEEK_SET); - wrmyrohdr(fp, &hdr); - - if (fclose(fp)) - die("error writing the output file"); -} - -void -reloc(Symbol *sym, - unsigned flags, unsigned size, unsigned nbits, unsigned shift) -{ - size_t tmp; - Reloc *p; - - if (pass == 1) - return; - - if (relcap == relsiz) { - tmp = ((relcap + 1) * 3) / 2; - if ((p = realloc(relocs, tmp * sizeof(Reloc))) == NULL) { - tmp = relcap + 1; - p = xrealloc(relocs, tmp * sizeof(Reloc)); - } - relcap = tmp; - relocs = p; - } - - p = &relocs[relsiz++]; - p->sym = sym; - p->flags = flags; - p->size = size; - p->nbits = nbits; - p->shift = shift; - p->offset = cursec->pc - cursec->base; -} diff --git a/as/parser.c b/as/parser.c @@ -1,482 +0,0 @@ -static char sccsid[] = "@(#) ./as/parser.c"; -#include <assert.h> -#include <ctype.h> -#include <errno.h> -#include <limits.h> -#include <setjmp.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <cstd.h> -#include "../inc/scc.h" -#include "as.h" - -#define NARGS 20 -#define NR_INPUTS 10 -#define MAXLINE 100 - -struct input { - char *fname; - unsigned lineno; - FILE *fp; -}; - -int nerrors; -jmp_buf recover; -char yytext[INTIDENTSIZ+1]; -int yytoken; -size_t yylen; -union yylval yylval; - -static char *textp, *endp; -static int regmode; -static unsigned lineno; -static struct input inputs[NR_INPUTS], *isp = inputs; - -static int -follow(int expect1, int expect2, int ifyes1, int ifyes2, int ifno) -{ - int c; - - if ((c = *++textp) == expect1) - return ifyes1; - if (c == expect2) - return ifyes2; - --textp; - return ifno; -} - -static void -tok2str(void) -{ - if ((yylen = endp - textp) > INTIDENTSIZ) { - error("token too big"); - yylen = INTIDENTSIZ; - } - memcpy(yytext, textp, yylen); - yytext[yylen] = '\0'; - textp = endp; -} - -static int -iden(void) -{ - int c; - char *p; - - for ( ; c = *endp; ++endp) { - if (isalnum(c)) - continue; - switch (c) { - case '\'': - case '_': - case '-': - case '.': - case '$': - continue; - default: - goto out_loop; - } - } - -out_loop: - tok2str(); - yylval.sym = lookup(yytext); - - return (yylval.sym->flags & FREG) ? REG : IDEN; -} - -static int -number(void) -{ - int c, base = 10; - char *p; - TUINT n; - - if (*endp == '0') { - base = 8; - ++endp; - if (*endp == 'x') { - base = 16; - ++endp; - } - } - for (n = 0; (c = *endp) && isxdigit(c); n += c) { - n *= base; - c -= '0'; - if (n >= TUINT_MAX - c*base) - error("overflow in number"); - endp++; - } - tok2str(); - yylval.sym = tmpsym(n); - - return NUMBER; -} - -static int -character(void) -{ - int c; - char *p; - - while (*endp != '\'') - ++endp; - return NUMBER; -} - -static int -string(void) -{ - int c; - size_t l; - char *s; - Symbol *sym = tmpsym(0); - - for (++endp; *endp != '"'; ++endp) - ; - ++endp; - tok2str(); - yylval.sym = sym; - /* FIXME: this memory is not freed ever */ - l = yylen-2; - s = memcpy(xmalloc(l+1), yytext+1, l); - s[l] = '\0'; - sym->name.buf = s; - - return STRING; -} - -static int -operator(void) -{ - int c; - - ++endp; - if ((c = *textp) == '>') - c = follow('=', '>', LE, SHL, '>'); - else if (c == '<') - c = follow('=', '<', GE, SHR, '>'); - tok2str(); - - return c; -} - -int -next(void) -{ - int c; - - while (isspace(*textp)) - ++textp; - - endp = textp; - - switch (c = *textp) { - case '\0': - strcpy(yytext, "EOS"); - yylen = 3; - c = EOS; - break; - case '"': - c = string(); - break; - case '\'': - c = character(); - break; - case '%': - c = (regmode ? iden : operator)(); - break; - case '_': - c = iden(); - break; - default: - if (isdigit(c)) - c = number(); - else if (isalpha(c)) - c = iden(); - else - c = operator(); - break; - } - return yytoken = c; -} - -void -expect(int token) -{ - if (yytoken != token) - unexpected(); - next(); -} - -void -unexpected(void) -{ - error("unexpected '%s'", yytext); -} - -void -error(char *msg, ...) -{ - va_list va; - struct input *ip; - - assert(isp > inputs); - ip = &isp[-1]; - - va_start(va, msg); - fprintf(stderr, "as:%s:%u: ", ip->fname, ip->lineno); - vfprintf(stderr, msg, va); - putc('\n', stderr); - nerrors++; - va_end(va); - - if (nerrors == 10) - die("as: too many errors"); - longjmp(recover, 1); -} - -Node * -getreg(void) -{ - Node *np; - - np = node(REG, NULL, NULL); - np->sym = yylval.sym; - np->addr = AREG; - expect(REG); - return np; -} - -void -regctx(int mode) -{ - regmode = mode; -} - -Node * -operand(char **strp) -{ - int imm = 0; - Node *np; - - textp = *strp; - regctx(1); - switch (next()) { - case EOS: - np = NULL; - break; - case REG: - np = getreg(); - break; - case STRING: - np = node(yytoken, NULL, NULL); - np->sym = yylval.sym; - np->addr = ASTR; - next(); - break; - case '$': - next(); - imm = 1; - default: - if (!imm) { - np = moperand(); - } else { - np = expr(); - np->addr = AIMM; - } - } - if (yytoken != ',' && yytoken != EOS) - error("trailing characters in expression '%s'", textp); - *strp = endp; - - return np; -} - -Node ** -getargs(char *s) -{ - Node **ap; - static Node *args[NARGS]; - - if (!s) - return NULL; - - for (ap = args; ap < &args[NARGS-1]; ++ap) { - if ((*ap = operand(&s)) == NULL) - return args; - } - error("too many arguments in one instruction"); -} - -static char * -field(char **oldp, size_t *siz) -{ - char *s, *t, *begin; - size_t n; - - if ((begin = *oldp) == NULL) - return NULL; - - for (s = begin; isspace(*s) && *s != '\t'; ++s) - ; - if (*s == '\0' || *s == '/' || *s == ';') { - *s = '\0'; - return *oldp = NULL; - } - - for (t = s; *t && *t != '\t'; ++t) - ; - if (*t == '\t') - *t++ = '\0'; - *siz -= begin - t; - *oldp = t; - - while (t >= s && isspace(*t)) - *t-- = '\0'; - return (*s != '\0') ? s : NULL; -} - -static int -validlabel(char *name) -{ - int c; - - while ((c = *name++) != '\0') { - if (isalnum(c)) - continue; - switch (c) { - case '_': - case '-': - case '.': - case '$': - continue; - case ':': - if (*name != '\0') - return 0; - *--name = '\0'; - continue; - default: - return 0; - } - } - return 1; -} - -static int -extract(char *s, size_t len, struct line *lp) -{ - int r = 0; - - if (lp->label = field(&s, &len)) - r++; - if (lp->op = field(&s, &len)) - r++; - if (lp->args = field(&s, &len)) - r++; - - if (s && *s && *s != '/') - error("trailing characters at the end of the line"); - if (lp->label && !validlabel(lp->label)) - error("incorrect label name '%s'", lp->label); - - return r; -} - -static void -comment(FILE *fp) -{ - int c; - - while ((c = getc(fp)) != EOF) { - if (c != '*') - continue; - if ((c = getc(fp)) == '/') - return; - ungetc(c, fp); - } -} - -static size_t -getline(FILE *fp, char buff[MAXLINE]) -{ - int c; - char *bp; - - for (bp = buff; (c = getc(fp)) != EOF; *bp++ = c) { - if (c == '\n') - break; - if (c == '/') { - if ((c = getc(fp)) != '*') { - ungetc(c, fp); - c = '/'; - } else { - comment(fp); - c = ' '; - } - } else if (c > UCHAR_MAX) { - error("invalid character '%x'", c); - } - if (bp == &buff[MAXLINE-1]) - error("line too long"); - } - *bp = '\0'; - - return bp - buff; -} - -int -nextline(FILE *fp, struct line *lp) -{ - struct input *ip; - size_t n; - static char buff[MAXLINE]; - - assert(isp > inputs); -repeat: - if (isp == inputs) - return 0; - ip = &isp[-1]; - if (feof(ip->fp)) { - delinput(); - goto repeat; - } - n = getline(ip->fp, buff); - if (++ip->lineno == 0) - die("as: %s: file too long", infile); - if (n == 0) - goto repeat; - if (extract(buff, n, lp) == 0) - goto repeat; - return 1; -} - -void -addinput(char *fname) -{ - FILE *fp; - - if (isp == &inputs[NR_INPUTS]) - die("as: too many included files"); - if ((fp = fopen(fname, "r")) == NULL) - die("as: %s: %s", fname, strerror(errno)); - isp->fname = xstrdup(fname); - isp->fp = fp; - isp->lineno = 0; - ++isp; -} - -int -delinput(void) -{ - if (isp == inputs) - return EOF; - --isp; - if (fclose(isp->fp) == EOF) - die("as: %s: %s", isp->fname, strerror(errno)); - free(isp->fname); - return 0; -} diff --git a/as/symbol.c b/as/symbol.c @@ -1,291 +0,0 @@ -static char sccsid[] = "@(#) ./as/symbol.c"; - -#include <ctype.h> -#include <stdio.h> -#include <stdint.h> -#include <string.h> - -#include "../inc/scc.h" -#include "as.h" - -#define HASHSIZ 64 -#define NALLOC 10 - -Section *cursec, *seclist; -Section *sabs, *sbss, *sdata, *stext; -Symbol *linesym, *symlist; -int pass; - -static Symbol *hashtbl[HASHSIZ], *symlast; -static Alloc *tmpalloc; - - -#ifndef NDEBUG -void -dumpstab(char *msg) -{ - Symbol **bp, *sym; - - fprintf(stderr, "%s\n", msg); - for (bp = hashtbl; bp < &hashtbl[HASHSIZ]; ++bp) { - if (*bp == NULL) - continue; - - fprintf(stderr, "[%d]", (int) (bp - hashtbl)); - for (sym = *bp; sym; sym = sym->hash) { - fprintf(stderr, " -> %s:%0X:%0X", - sym->name.buf, sym->flags, sym->value); - } - putc('\n', stderr); - } -} -#endif - -Symbol * -lookup(char *name) -{ - unsigned h; - Symbol *sym, **list; - int c, symtype; - char *t, *s; - - h = 0; - for (s = name; c = *s; ++s) - h = h*33 ^ c; - h &= HASHSIZ-1; - - c = toupper(*name); - list = &hashtbl[h]; - for (sym = *list; sym; sym = sym->hash) { - t = sym->name.buf; - if (c == toupper(*t) && !casecmp(t, name)) - return sym; - } - - sym = xmalloc(sizeof(*sym)); - sym->name = newstring(name); - sym->flags = 0; - sym->size = sym->value = 0; - sym->section = cursec; - sym->hash = *list; - sym->next = NULL; - - *list = sym; - if (symlast) - symlast->next = sym; - symlast = sym; - if (!symlist) - symlist = sym; - - return sym; -} - -Symbol * -deflabel(char *name) -{ - static Symbol *cursym; - Symbol *sym; - char label[MAXSYM+1]; - - if (*name == '.') { - int r; - - if (!cursym) { - error("local label '%s' without global label", name); - return NULL; - } - r = snprintf(label, sizeof(label), - "%s%s", - cursym->name.buf, name); - if (r == sizeof(label)) { - error("local label '%s' in '%s' produces too long symbol", - name, cursym->name.buf); - return NULL; - } - name = label; - } - - sym = lookup(name); - if (pass == 1 && (sym->flags & FDEF)) - error("redefinition of label '%s'", name); - if (cursec->flags & SABS) - sym->flags |= FABS; - sym->flags |= FDEF; - sym->value = cursec->curpc; - sym->section = cursec; - - if (*name != '.') - cursym = sym; - return sym; -} - -int -toobig(Node *np, int type) -{ - /* TODO */ - return 0; -} - -static void -incpc(int siz) -{ - TUINT pc, curpc; - - pc = cursec->pc; - curpc = cursec->curpc; - - cursec->curpc += siz; - cursec->pc += siz; - - if (pass == 2) - return; - - if (cursec->pc > cursec->max) - cursec->max = cursec->pc; - - if (pc > cursec->pc || - curpc > cursec->curpc || - cursec->curpc > maxaddr || - cursec->pc > maxaddr) { - die("as: address overflow in section '%s'"); - } -} - -static int -secflags(char *attr) -{ - int c, flags; - - if (!attr) - return 0; - - for (flags = 0; c = *attr++; ) { - switch (c) { - case 'w': - flags |= SWRITE; - break; - case 'r': - flags |= SREAD; - break; - case 'x': - flags |= SEXEC; - break; - case 'f': - flags |= SFILE; - break; - case 'l': - flags |= SLOAD; - break; - case 'a': - flags |= SABS; - break; - } - } - - return flags; -} - -Section * -setsec(char *name, char *attr) -{ - Section *sec; - Symbol *sym; - - cursec = NULL; - sym = lookup(name); - if (sym->flags & ~FSECT) - error("invalid section name '%s'", name); - - if ((sec = sym->section) == NULL) { - sec = xmalloc(sizeof(*sec)); - sec->mem = NULL; - sec->sym = sym; - sec->base = sec->max = sec->pc = sec->curpc = 0; - sec->next = seclist; - sec->flags = 0; - sec->fill = 0; - sec->aligment = 0; - sec->next = seclist; - seclist = sec; - - sym->section = sec; - sym->flags = FSECT; - } - sec->flags |= secflags(attr); - - return cursec = sec; -} - -void -isecs(void) -{ - sabs = setsec(".abs", "rwx"); - sbss = setsec(".bss", "rwf"); - sdata = setsec(".data", "rw"); - stext = setsec(".text", "rx"); -} - -void -cleansecs(void) -{ - Section *sec; - TUINT siz; - - for (sec = seclist; sec; sec = sec->next) { - sec->curpc = sec->pc = sec->base; - if (pass == 1 || sec->flags & SFILE) - continue; - - siz = sec->max - sec->base; - if (siz > SIZE_MAX) - die("as: out of memory"); - sec->mem = xmalloc(sec->max - sec->base); - } - cursec = stext; -} - -void -emit(char *bytes, int n) -{ - if (cursec->mem) { - size_t len = cursec->pc - cursec->base; - memcpy(&cursec->mem[len], bytes, n); - } - incpc(n); -} - -Symbol * -tmpsym(TUINT val) -{ - Symbol *sym; - - if (!tmpalloc) - tmpalloc = alloc(sizeof(*sym), NALLOC); - sym = new(tmpalloc); - sym->value = val; - sym->section = NULL; - sym->flags = FABS; - - return sym; -} - -void -killtmp(void) -{ - if (!tmpalloc) - return; - dealloc(tmpalloc); - tmpalloc = NULL; -} - -String -newstring(char *s) -{ - size_t len = strlen(s) + 1; - String str; - - str.offset = 0; - str.buf = xmalloc(len); - memcpy(str.buf, s, len); - return str; -} diff --git a/as/target/amd64.mk b/as/target/amd64.mk @@ -1,8 +0,0 @@ - -AMD64_OBJ = $(OBJ) target/x86/amd64tbl.o target/x86/amd64.o target/x86/ins.o - -target/x86/amd64tbl.c: gentbl.awk target/x86/x86.dat target/x86/rules.dat - ./gentbl.sh -f x86 -c amd64 - -$(LIBEXEC)/as-amd64: $(AMD64_OBJ) - $(CC) $(SCC_LDFLAGS) $(AMD64_OBJ) -lscc -o $@ diff --git a/as/target/i286.mk b/as/target/i286.mk @@ -1,8 +0,0 @@ - -I286_OBJ = $(OBJ) target/x86/i286tbl.o target/x86/i286.o target/x86/ins.o - -target/x86/i286tbl.c: gentbl.awk target/x86/x86.dat target/x86/rules.dat - ./gentbl.sh -f x86 -c i286 - -$(LIBEXEC)/as-i286: $(I286_OBJ) - $(CC) $(SCC_LDFLAGS) $(I286_OBJ) -lscc -o $@ diff --git a/as/target/i386.mk b/as/target/i386.mk @@ -1,8 +0,0 @@ - -I386_OBJ = $(OBJ) target/x86/i386tbl.o target/x86/i386.o target/x86/ins.o - -target/x86/i386tbl.c: gentbl.awk target/x86/x86.dat target/x86/rules.dat - ./gentbl.sh -f x86 -c i386 - -$(LIBEXEC)/as-i386: $(I386_OBJ) - $(CC) $(SCC_LDFLAGS) $(I386_OBJ) -lscc -o $@ diff --git a/as/target/x80/ins.c b/as/target/x80/ins.c @@ -1,600 +0,0 @@ -static char sccsid[] = "@(#) ./as/target/x80/ins.c"; - -#include <stdlib.h> -#include <string.h> - -#include "../../../inc/scc.h" -#include "../../as.h" -#include "proc.h" - -/* - * This implementation is based in: - * - Zilog Z80 CPU Specifications by Sean Young - * - Decoding Z80 opcodes - of use to disassembler and emulator - * writers - by Cristian Dinu. - */ - -static int -getclass(Node *np) -{ - if (np->addr != AREG) - return 0; - - switch (np->sym->value) { - case AREG_C: - return RCLASS | PCLASS | QCLASS | CCCLASS | SSCLASS; - case AREG_A: - case AREG_B: - case AREG_D: - case AREG_E: - return RCLASS | PCLASS | QCLASS; - case AREG_H: - case AREG_L: - return RCLASS; - case AREG_IXL: - case AREG_IXH: - return PCLASS; - case AREG_IYL: - case AREG_IYH: - return QCLASS; - case AREG_HL: - return DDCLASS | QQCLASS; - case AREG_BC: - case AREG_DE: - return DDCLASS | QQCLASS | PPCLASS | RRCLASS; - case AREG_SP: - return DDCLASS | PPCLASS | RRCLASS; - case AREG_AF: - return QQCLASS; - case AREG_IX: - return PPCLASS; - case AREG_IY: - return RRCLASS; - case AREG_PO: - case AREG_PE: - case AREG_P: - case AREG_M: - return CCCLASS; - case AREG_NZ: - case AREG_Z: - case AREG_NC: - return CCCLASS | SSCLASS; - default: - return 0; - } -} - -int -match(Op *op, Node **args) -{ - unsigned char *p; - int arg, class, rep, opt; - Node *np; - - if (!op->args) - return args == NULL; - - opt = rep = 0; - for (p = op->args; arg = *p; ++p) { - if (rep) - --p; - if ((np = *args++) == NULL) - return (rep|opt) != 0; - - switch (arg) { - case AOPT: - opt = 1; - break; - case AREP: - rep = 1; - break; - case AINDER_C: - arg = AREG_C; - goto indirect; - case AINDER_HL: - arg = AREG_HL; - goto indirect; - case AINDER_DE: - arg = AREG_DE; - goto indirect; - case AINDER_BC: - arg = AREG_BC; - goto indirect; - case AINDER_IX: - arg = AREG_IX; - goto indirect; - case AINDER_IY: - arg = AREG_IY; - goto indirect; - case AINDER_SP: - arg = AREG_SP; - indirect: - if (np->addr != AINDIR) - return 0; - np = np->left; - case AREG_A: - case AREG_I: - case AREG_R: - case AREG_F: - case AREG_HL: - case AREG_BC: - case AREG_DE: - case AREG_IY: - case AREG_IX: - case AREG_SP: - case AREG_AF: - case AREG_AF_: - if (np->addr != AREG || np->sym->value != arg) - return 0; - break; - case AREG_RCLASS: - class = RCLASS; - goto check_class; - case AREG_PCLASS: - class = PCLASS; - goto check_class; - case AREG_QCLASS: - class = QCLASS; - goto check_class; - case AREG_QQCLASS: - class = QQCLASS; - goto check_class; - case AREG_PPCLASS: - class = PPCLASS; - goto check_class; - case AREG_RRCLASS: - class = RRCLASS; - goto check_class; - case AREG_CCCLASS: - class = CCCLASS; - goto check_class; - case AREG_SSCLASS: - class = SSCLASS; - goto check_class; - case AREG_DDCLASS: - class = DDCLASS; - check_class: - if ((getclass(np) & class) == 0) - return 0; - break; - case AINDEX_IY: - arg = AREG_IY; - goto index_address; - case AINDEX_IX: - arg = AREG_IX; - index_address: - if (np->addr != AINDEX) - return 0; - if (np->left->left->sym->value != arg) - return 0; - if (toobig(np, arg)) - error("overflow in index"); - break; - case ARST: - if (np->addr != AIMM) - return 0; - if ((np->sym->value & ~0x38) != 0) - return 0; - break; - case AZERO: - case AIMM3: - case AIMM8: - case AIMM16: - case AIMM32: - case AIMM64: - if (np->addr != AIMM) - return 0; - if (toobig(np, arg)) - error("overflow in immediate operand"); - break; - case ASYM: - if (np->addr != AIMM || np->op != IDEN) - return 0; - break; - case ADIRECT: - case ASTR: - if (np->addr != arg) - return 0; - break; - default: - abort(); - } - } - - return *args == NULL; -} - -/* - * (expr) -> ADIRECT - * (REG) -> AINDIR - * (REG + expr) -> AINDEX - * (REG - expr) -> AINDEX - * expr (REG) -> AINDEX - */ -Node * -moperand(void) -{ - int op; - Node *np, *dir, *off, *reg; - - dir = off = reg = NULL; - if (accept('(')) { - if (yytoken != REG) { - dir = expr(); - } else { - reg = getreg(); - switch (yytoken) { - case '+': - case '-': - off = expr(); - case ')': - break; - default: - unexpected(); - } - } - } else { - off = expr(); - expect('('); - reg = getreg(); - } - expect(')'); - - if (dir) { - op = ADIRECT; - np = dir; - } else if (off) { - np = node(AREG_OFF, reg, off); - op = AINDEX; - } else { - np = reg; - op = AINDIR; - } - np = node(op, np, NULL); - np->addr = op; - return np; -} - -static int -reg2int(Node *np) -{ - switch (np->sym->value) { - case AREG_F: - case AREG_B: return 0; - case AREG_C: return 1; - case AREG_D: return 2; - case AREG_E: return 3; - case AREG_IXH: - case AREG_IYH: - case AREG_H: return 4; - case AREG_IXL: - case AREG_IYL: - case AREG_L: return 5; - case AREG_A: return 7; - case AREG_BC: return 0; - case AREG_DE: return 1; - case AREG_HL: - case AREG_IX: - case AREG_IY: return 2; - case AREG_AF: - case AREG_SP: return 3; - default: abort(); - } -} - -static int -cc2int(Node *np) -{ - switch (np->sym->value) { - case AREG_NZ: return 0; - case AREG_Z: return 1; - case AREG_NC: return 2; - case AREG_C: return 3; - case AREG_PO: return 4; - case AREG_PE: return 5; - case AREG_P: return 6; - case AREG_M: return 7; - default: abort(); - } -} - -static int -ss2int(Node *np) -{ - switch (np->sym->value) { - case AREG_NZ: return 4; - case AREG_Z: return 5; - case AREG_NC: return 6; - case AREG_C: return 7; - default: abort(); - } -} - -void -dir(Op *op, Node **args) -{ - Node *imm; - unsigned char buf[4]; - unsigned val; - int n = op->size; - - imm = (args[1]->addr == ADIRECT) ? args[1] : args[0]; - imm = imm->left; - memcpy(buf, op->bytes, n); - val = imm->sym->value; - buf[n-1] = val >> 8; - buf[n-2] = val; - emit(buf, n); -} - -void -ld8(Op *op, Node **args) -{ - Node *par1 = args[0], *par2 = args[1]; - int n = op->size, i = n;; - unsigned regval = 0; - unsigned char buf[4]; - - memcpy(buf, op->bytes, n); - - if (par1->addr == AREG) - regval |= reg2int(par1) << 3; - if (par2->addr == AREG) - regval |= reg2int(par2); - else if (par2->addr == AIMM) - buf[--i] = par2->sym->value; - - buf[--i] |= regval; - emit(buf, n); -} - -void -alu16(Op *op, Node **args) -{ - Node *par; - int n = op->size; - unsigned val; - unsigned char buf[4]; - - par = (args[1]) ? args[1] : args[0]; - val = reg2int(par); - memcpy(buf, op->bytes, n); - buf[n-1] |= val << 4; - emit(buf, n); -} - -void -ld16(Op *op, Node **args) -{ - Node *dst, *src, *tmp; - int n = op->size; - unsigned val; - unsigned char buf[4]; - - dst = args[0]; - src = args[1]; - if (!src) { - alu16(op, args); - return; - } - - if (dst->addr != AREG) { - tmp = src; - src = dst; - dst = tmp; - } - - memcpy(buf, op->bytes, n); - if (src->addr == ADIRECT) - src = src->left; - val = src->sym->value; - buf[n-1] = val >> 8; - buf[n-2] = val; - buf[n-3] |= reg2int(dst) << 4; - emit(buf, n); -} - -void -alu8(Op *op, Node **args) -{ - Node *par = args[1]; - unsigned char buf[4]; - int n = op->size, shift; - unsigned val; - - if (args[1]) { - shift = 0; - par = args[1]; - } else { - shift = 3; - par = args[0]; - } - - switch (par->addr) { - case AIMM: - val = par->sym->value; - break; - case AREG: - val = reg2int(par) << shift; - break; - case AINDEX: - val = par->left->right->sym->value; - break; - case AINDIR: - val = 0; - break; - default: - abort(); - } - - memcpy(buf, op->bytes, n); - buf[n-1] |= val; - emit(buf, n); -} - -void -idx(Op *op, Node **args) -{ - Node *tmp, *idx, *imm, *reg; - unsigned char buf[4]; - int n = op->size, i = n, shift = 0; - - imm = reg = NULL; - if (args[0]->addr != AINDEX) { - shift = 3; - tmp = args[0]; - args[0] = args[1]; - args[1] = tmp; - } - idx = args[0]->left->right; - - if (args[1]->addr == AREG) - reg = args[1]; - else - imm = args[1]; - - memcpy(buf, op->bytes, n); - - if (imm) - buf[--i] = imm->sym->value; - buf[--i] = idx->sym->value; - if (reg) - buf[--i] |= reg2int(reg) << shift; - - emit(buf, n); -} - -void -inout(Op *op, Node **args) -{ - Node *port, *value; - unsigned val; - int n = op->size; - unsigned char buf[5]; - - port = args[0]; - value = args[1]; - if (port->addr != ADIRECT && port->addr != AINDIR) { - value = port; - port = args[1]; - } - - if (port->addr == ADIRECT) - val = port->left->sym->value; - else if (value->addr == AREG) - val = reg2int(value) << 3; - else - val = 0; - - memcpy(buf, op->bytes, n); - buf[n-1] |= val; - emit(buf, n); -} - -void -rot_bit(Op *op, Node **args) -{ - Node *par = args[0]; - unsigned char buf[5]; - int n = op->size; - unsigned val, npar = 0; - - memcpy(buf, op->bytes, n); - - par = args[0]; - if (par->addr == AIMM) { - buf[n-1] |= par->sym->value << 3; - par = args[npar = 1]; - } - - switch (par->addr) { - case AINDEX: - val = par->left->right->sym->value; - buf[n-2] = val; - par = args[npar+1]; - if (!par) - break; - case AREG: - val = reg2int(par); - buf[n-1] |= val; - case AINDIR: - break; - default: - abort(); - } - - emit(buf, n); -} - -void -im(Op *op, Node **args) -{ - unsigned val = args[0]->sym->value; - unsigned char buf[4]; - int n = op->size; - - if (val > 0) - ++val; - - memcpy(buf, op->bytes, n); - buf[n-1] |= val << 3; - emit(buf, n); -} - -void -branch(int relative, Op *op, Node **args) -{ - unsigned char buf[4]; - Node *flag, *imm; - int n = op->size, i = n; - unsigned val; - int (*fun)(Node *); - - flag = imm = NULL; - if (args[0]->addr == AREG) { - flag = args[0]; - imm = args[1]; - } else if (args[0]->addr == AIMM) { - imm = args[0]; - } - memcpy(buf, op->bytes, n); - - if (imm) { - val = imm->sym->value; - if (!relative) - buf[--i] = val >> 8; - else - val -= cursec->curpc - 2; - buf[--i] = val; - - } - if (flag) { - fun = (relative) ? ss2int : cc2int; - buf[--i] |= (*fun)(flag) << 3; - } - - - emit(buf, n); -} - -void -jp(Op *op, Node **args) -{ - branch(0, op, args); -} - -void -jr(Op *op, Node **args) -{ - branch(1, op, args); -} - -void -rst(Op *op, Node **args) -{ - unsigned char buf[1]; - - buf[0] = op->bytes[0]; - buf[0] |= args[0]->sym->value; - emit(buf, 1); -} diff --git a/as/target/x80/z80.c b/as/target/x80/z80.c @@ -1,64 +0,0 @@ -static char sccsid[] = "@(#) ./as/target/x80/z80.c"; - -#include <stdlib.h> - -#include "../../../inc/scc.h" -#include "../../as.h" -#include "../x80/proc.h" - -TUINT maxaddr = 0xFFFFFFFF; -int endian = LITTLE_ENDIAN; - -void -iarch(void) -{ - static struct { - char *name; - char type; - } regs[] = { - "AF", AREG_AF, - "A", AREG_A, - "F", AREG_F, - - "BC", AREG_BC, - "B", AREG_B, - "C", AREG_C, - - "HL", AREG_HL, - "H", AREG_H, - "L", AREG_L, - - "DE", AREG_DE, - "D", AREG_D, - "E", AREG_E, - - "IX", AREG_IX, - "IXL", AREG_IXL, - "IXH", AREG_IXH, - - "IY", AREG_IY, - "IYL", AREG_IYL, - "IYH", AREG_IYH, - - "R", AREG_R, - "I", AREG_I, - "AF'", AREG_AF_, - "SP", AREG_SP, - - "NZ", AREG_NZ, - "Z", AREG_Z, - "NC", AREG_NC, - "PO", AREG_PO, - "PE", AREG_PE, - "P", AREG_P, - "M", AREG_M, - - NULL, - }, *bp; - - for (bp = regs; bp->name; ++bp) { - Symbol *sym = lookup(bp->name); - sym->flags = FREG; - sym->value = bp->type; - } -} diff --git a/as/target/x86/amd64.c b/as/target/x86/amd64.c @@ -1,12 +0,0 @@ -static char sccsid[] = "@(#) ./as/target/x86/amd64.c"; - -#include "../../../inc/scc.h" -#include "../../as.h" - -TUINT maxaddr = 0xFFFFFFFFFFFFFFFF; -int endian = LITTLE_ENDIAN; - -void -iarch(void) -{ -} diff --git a/as/target/x86/i286.c b/as/target/x86/i286.c @@ -1,53 +0,0 @@ -static char sccsid[] = "@(#) ./as/target/x86/i286.c"; - -#include "../../../inc/scc.h" -#include "../../as.h" -#include "../x86/proc.h" - -TUINT maxaddr = 0xFFFF; -int endian = LITTLE_ENDIAN; -int left2right = 0; - -void -iarch(void) -{ - static struct { - char *name; - char type; - } regs[] = { - "CS", AREG_CS, - "DS", AREG_DS, - "SS", AREG_SS, - "ES", AREG_ES, - - "AX", AREG_AX, - "AL", AREG_AL, - "AH", AREG_AH, - - "BX", AREG_BX, - "BL", AREG_BL, - "BH", AREG_BH, - - "CX", AREG_CX, - "CL", AREG_CL, - "CH", AREG_CH, - - "DX", AREG_DX, - "DL", AREG_DL, - "DH", AREG_DH, - - "SI", AREG_SI, - "DI", AREG_DI, - - "SP", AREG_SP, - "BP", AREG_BP, - - NULL - }, *bp; - - for (bp = regs; bp->name; ++bp) { - Symbol *sym = lookup(bp->name); - sym->flags = FREG; - sym->value = bp->type; - } -} diff --git a/as/target/x86/i386.c b/as/target/x86/i386.c @@ -1,100 +0,0 @@ -static char sccsid[] = "@(#) ./as/target/x86/i386.c"; - -#include "../../../inc/scc.h" -#include "../../as.h" -#include "../x86/proc.h" - -TUINT maxaddr = 0xFFFFFFFF; -int endian = LITTLE_ENDIAN; - -void -iarch(void) -{ - static struct { - char *name; - char type; - } regs[] = { - "CS", AREG_CS, - "DS", AREG_DS, - "SS", AREG_SS, - "ES", AREG_ES, - "FS", AREG_FS, - "GS", AREG_GS, - - "AX", AREG_AX, - "AL", AREG_AL, - "AH", AREG_AH, - "EAX", AREG_EAX, - - "BC", AREG_BX, - "BL", AREG_BL, - "BH", AREG_BH, - "EBX", AREG_EBX, - - "CX", AREG_CX, - "CL", AREG_CL, - "CH", AREG_CH, - "ECX", AREG_ECX, - - "DX", AREG_DX, - "DL", AREG_DL, - "DH", AREG_DH, - "EDX", AREG_EDX, - - "SI", AREG_SI, - "ESI", AREG_ESI, - "DI", AREG_DI, - "EDI", AREG_EDI, - - "SP", AREG_SP, - "ESP", AREG_ESP, - - "BP", AREG_BP, - "EBP", AREG_EBP, - - "R0", AREG_R0, - "MM0", AREG_MM0, - "R1", AREG_R1, - "MM1", AREG_MM1, - "R2", AREG_R2, - "MM2", AREG_MM2, - "R3", AREG_R3, - "MM3", AREG_MM3, - "R4", AREG_R4, - "MM4", AREG_MM4, - "R5", AREG_R5, - "MM5", AREG_MM5, - "R6", AREG_R6, - "MM6", AREG_MM6, - "R7", AREG_R7, - "MM7", AREG_MM7, - - "XMM0", AREG_XMM0, - "XMM1", AREG_XMM1, - "XMM2", AREG_XMM2, - "XMM3", AREG_XMM3, - "XMM4", AREG_XMM4, - "XMM5", AREG_XMM5, - "XMM6", AREG_XMM6, - "XMM7", AREG_XMM7, - - "YMM0", AREG_YMM0, - "YMM1", AREG_YMM1, - "YMM2", AREG_YMM2, - "YMM3", AREG_YMM3, - "YMM4", AREG_YMM4, - "YMM5", AREG_YMM5, - "YMM6", AREG_YMM6, - "YMM7", AREG_YMM7, - - "MXCSR", AREG_MXCSR, - - NULL - }, *bp; - - for (bp = regs; bp->name; ++bp) { - Symbol *sym = lookup(bp->name); - sym->flags = FREG; - sym->value = bp->type; - } -} diff --git a/as/target/x86/ins.c b/as/target/x86/ins.c @@ -1,301 +0,0 @@ -static char sccsid[] = "@(#) ./as/target/x86/ins.c"; - -#include <stdlib.h> - -#include "../../../inc/scc.h" -#include "../../as.h" -#include "proc.h" - -#define addrbyte(mod, reg, rm) ((mod) << 6 | (reg) << 3 | (rm)) - -enum addr_mode { - MEM_MODE = 0, - MEM8_MODE = 1, - MEM16_MODE = 2, - REG_MODE = 3, -}; - -static int -getclass(Node *np) -{ - if (np->addr != AREG) - return 0; - - switch (np->sym->value) { - case AREG_AL: - case AREG_AH: - case AREG_BL: - case AREG_BH: - case AREG_CL: - case AREG_CH: - case AREG_DL: - case AREG_DH: - return R8CLASS; - - case AREG_AX: - case AREG_BX: - case AREG_CX: - case AREG_DX: - case AREG_DI: - case AREG_SI: - case AREG_SP: - case AREG_BP: - return R16CLASS; - - case AREG_CS: - case AREG_DS: - case AREG_SS: - case AREG_ES: - case AREG_FS: - case AREG_GS: - - case AREG_EFLAGS: - case AREG_CF: - case AREG_PF: - case AREG_AF: - case AREG_ZF: - case AREG_SF: - case AREG_TF: - case AREG_IF: - case AREG_DF: - case AREG_OF: - case AREG_IOPL: - case AREG_NT: - case AREG_RF: - case AREG_VM: - case AREG_AC: - case AREG_VIF: - case AREG_VIP: - case AREG_ID: - - case AREG_EAX: - case AREG_RAX: - - case AREG_EBX: - case AREG_RBX: - - case AREG_ECX: - case AREG_RCX: - - case AREG_EDX: - case AREG_RDX: - - case AREG_SIL: - case AREG_ESI: - case AREG_RSI: - case AREG_DIL: - case AREG_EDI: - case AREG_RDI: - - case AREG_SPL: - case AREG_ESP: - case AREG_RSP: - - case AREG_BPL: - case AREG_EBP: - case AREG_RBP: - - case AREG_R0: - case AREG_MM0: - case AREG_R1: - case AREG_MM1: - case AREG_R2: - case AREG_MM2: - case AREG_R3: - case AREG_MM3: - case AREG_R4: - case AREG_MM4: - case AREG_R5: - case AREG_MM5: - case AREG_R6: - case AREG_MM6: - case AREG_R7: - case AREG_MM7: - - case AREG_R8: - case AREG_R8L: - case AREG_R8W: - case AREG_R9: - case AREG_R9L: - case AREG_R9W: - case AREG_R10: - case AREG_R10L: - case AREG_R10W: - case AREG_R11: - case AREG_R11L: - case AREG_R11W: - case AREG_R12: - case AREG_R12L: - case AREG_R12W: - case AREG_R13: - case AREG_R13L: - case AREG_R13W: - case AREG_R14: - case AREG_R14L: - case AREG_R14W: - case AREG_R15: - case AREG_R15L: - case AREG_R15W: - - case AREG_XMM0: - case AREG_XMM1: - case AREG_XMM2: - case AREG_XMM3: - case AREG_XMM4: - case AREG_XMM5: - case AREG_XMM6: - case AREG_XMM7: - case AREG_XMM8: - case AREG_XMM9: - case AREG_XMM10: - case AREG_XMM11: - case AREG_XMM12: - case AREG_XMM13: - case AREG_XMM14: - case AREG_XMM15: - - case AREG_YMM0: - case AREG_YMM1: - case AREG_YMM2: - case AREG_YMM3: - case AREG_YMM4: - case AREG_YMM5: - case AREG_YMM6: - case AREG_YMM7: - case AREG_YMM8: - case AREG_YMM9: - case AREG_YMM10: - case AREG_YMM11: - case AREG_YMM12: - case AREG_YMM13: - case AREG_YMM14: - case AREG_YMM15: - - case AREG_MXCSR: - return 0; - default: - abort(); - } -} - -int -match(Op *op, Node **args) -{ - unsigned char *p; - int arg, class, rep, opt; - Node *np; - - if (!op->args) - return args == NULL; - - opt = rep = 0; - for (p = op->args; arg = *p; ++p) { - if (rep) - --p; - if ((np = *args++) == NULL) - return (rep|opt) != 0; - - switch (arg) { - case AOPT: - opt = 1; - break; - case AREP: - rep = 1; - break; - case AREG_R8CLASS: - class = R8CLASS; - goto check_class; - case AREG_R16CLASS: - class = R16CLASS; - check_class: - if ((getclass(np) & class) == 0) - return 0; - break; - case AIMM8: - case AIMM16: - case AIMM32: - case AIMM64: - if (np->addr != AIMM) - return 0; - if (toobig(np, arg)) - error("overflow in immediate operand"); - break; - case ASYM: - if (np->addr != AIMM || np->op != IDEN) - return 0; - break; - case ADIRECT: - case ASTR: - if (np->addr != arg) - return 0; - break; - default: - abort(); - } - } - - return *args == NULL; -} - -Node * -moperand(void) -{ -} - -static int -reg8toint(Node *np) -{ - switch (np->sym->value) { - case AREG_AL: return 0; - case AREG_CL: return 1; - case AREG_DL: return 2; - case AREG_BL: return 3; - case AREG_AH: return 4; - case AREG_CH: return 5; - case AREG_DH: return 6; - case AREG_BH: return 7; - default: abort(); - } -} - -void -reg8_reg8(Op *op, Node **args) -{ - int src, dst; - char buf[2]; - - src = reg8toint(args[0]); - dst = reg8toint(args[1]); - buf[0] = op->bytes[0]; - buf[1] = addrbyte(REG_MODE, src, dst); - emit(buf, 2); -} - -static int -reg16toint(Node *np) -{ - switch (np->sym->value) { - case AREG_AX: return 0; - case AREG_CX: return 1; - case AREG_DX: return 2; - case AREG_BX: return 3; - case AREG_SP: return 4; - case AREG_BP: return 5; - case AREG_SI: return 6; - case AREG_DI: return 7; - default: abort(); - } -} - -void -reg16_reg16(Op *op, Node **args) -{ - int src, dst; - char buf[2]; - - src = reg16toint(args[0]); - dst = reg16toint(args[1]); - buf[0] = op->bytes[0]; - buf[1] = addrbyte(REG_MODE, src, dst); - emit(buf, 2); -} diff --git a/as/target/z80.mk b/as/target/z80.mk @@ -1,8 +0,0 @@ - -Z80_OBJ = $(OBJ) target/x80/z80tbl.o target/x80/z80.o target/x80/ins.o - -target/x80/z80tbl.c: gentbl.awk target/x80/x80.dat target/x80/rules.dat - ./gentbl.sh -f x80 -c z80 - -$(LIBEXEC)/as-z80: $(OBJ) $(Z80_OBJ) - $(CC) $(SCC_LDFLAGS) $(Z80_OBJ) -lscc -o $@ diff --git a/cc1/Makefile b/cc1/Makefile @@ -1,32 +0,0 @@ -.POSIX: - -PROJECTDIR = .. - -include $(PROJECTDIR)/rules.mk -include $(LIBSCC)/libdep.mk - -MORECFLAGS = -I$(INCLUDE)/$(STD) - -OBJ = types.o decl.o lex.o error.o symbol.o main.o expr.o \ - code.o stmt.o cpp.o fold.o init.o builtin.o - -TARGETS = $(LIBEXEC)/cc1-amd64-sysv $(LIBEXEC)/cc1-arm64-sysv \ - $(LIBEXEC)/cc1-i386-sysv $(LIBEXEC)/cc1-z80-scc - -all: $(TARGETS) - -$(TARGETS): $(LIBDIR)/libscc.a - -dep: - $(PROJECTDIR)/mkdep.sh - -clean: - rm -f *.o - rm -f target/*/*.o - rm -f $(TARGETS) - -include target/amd64-sysv/arch.mk -include target/arm64-sysv/arch.mk -include target/i386-sysv/arch.mk -include target/z80-scc/arch.mk -include deps.mk diff --git a/cc1/builtin.c b/cc1/builtin.c @@ -1,121 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/builtin.c"; - -#include <stdio.h> - -#include "../inc/scc.h" -#include "cc1.h" - -static Node * -builtin_va_arg(Symbol *sym) -{ - Node *np, *ap; - Type *tp; - - ap = assign(); - expect(','); - tp = typename(); - - if (!valid_va_list(ap->type)) { - errorp("incorrect parameters for va_arg"); - goto error; - } - if (tp == booltype || - tp == chartype || tp == uchartype || tp == schartype || - tp == shortype || tp == ushortype) { - warn("bool, char and short are promoted to int when passed through '...'"); - tp = (tp->prop & TSIGNED) ? inttype : uinttype; - } - - np = node(OBUILTIN, tp, ap, NULL); - np->sym = sym; - return np; - -error: - return constnode(zero); -} - -static Node * -builtin_va_copy(Symbol *sym) -{ - Node *np, *src, *dst; - - dst = assign(); - expect(','); - src = assign(); - - if (!valid_va_list(dst->type) || !valid_va_list(src->type)) { - errorp("incorrect parameters for va_copy"); - return constnode(zero); - } - - np = node(OBUILTIN, voidtype, dst, src); - np->sym = sym; - return np; -} - -static Node * -builtin_va_start(Symbol *sym) -{ - Node *np, *ap, *last; - Symbol **p; - Type *tp; - - ap = assign(); - expect(','); - last = assign(); - if (last->op != OSYM) - goto error; - - if (!valid_va_list(ap->type) || !(last->sym->flags&SDECLARED)) - goto error; - - for (p = curfun->u.pars; p && *p != last->sym; ++p) - ; - if (!p || *p == NULL || p[1] == NULL || p[1]->type != ellipsistype) - warn("second parameter of 'va_start' not last named argument"); - - tp = last->type; - if (tp == booltype || - tp == chartype || tp == uchartype || tp == schartype || - tp == shortype || tp == ushortype) { - warn("last parameter before '...' must not be bool, char or short"); - } - - np = node(OBUILTIN, voidtype, ap, last); - np->sym = sym; - return np; - -error: - errorp("incorrect parameters for va_start"); - return constnode(zero); -} - -static Node * -builtin_va_end(Symbol *sym) -{ - Node *ap, *np; - - ap = assign(); - - if (!valid_va_list(ap->type)) { - errorp("incorrect parameters for va_end"); - return constnode(zero); - } - - np = node(OBUILTIN, voidtype, ap, NULL); - np->sym = sym; - return np; -} - -void -ibuilts(void) -{ - struct builtin built[] = { - {"__builtin_va_arg", builtin_va_arg}, - {"__builtin_va_copy", builtin_va_copy}, - {"__builtin_va_start", builtin_va_start}, - {"__builtin_va_end", builtin_va_end}, - {NULL} - }; - builtins(built); -} diff --git a/cc1/code.c b/cc1/code.c @@ -1,550 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/code.c"; -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> - -#include "../inc/scc.h" -#include "cc1.h" - -static void emitbin(int, void *), - emitcast(int, void *), - emitsym(int, void *), - emitexp(int, void *), - emitsymid(int, void *), - emittext(int, void *), - emitfun(int, void *), - emitdcl(int, void *), - emitinit(int, void *), - emittype(int, void *), - emitbuilt(int, void *); - -char *optxt[] = { - [OADD] = "+", - [OSUB] = "-", - [OMUL] = "*", - [OINC] = ":i", - [ODEC] = ":d", - [OPTR] = "@", - [OMOD] = "%", - [ODIV] = "/", - [OSHL] = "l", - [OSHR] = "r", - [OLT] = "<", - [OGT] = ">", - [OGE] = "]", - [OLE] = "[", - [OEQ] = "=", - [ONE] = "!", - [OBAND] = "&", - [OBXOR] = "^", - [OBOR] = "|", - [OASSIGN] = ":", - [OA_MUL] = ":*", - [OA_DIV] = ":/", - [OA_MOD] = ":%", - [OA_ADD] = ":+", - [OA_SUB] = ":-", - [OA_SHL] = ":l", - [OA_SHR] = ":r", - [OA_AND] = ":&", - [OA_XOR] = ":^", - [OA_OR] = ":|", - [OADDR] = "'", - [OSNEG] = "_", - [ONEG] = "n", - [OCPL] = "~", - [OAND] = "a", - [OOR] = "o", - [OASK] = "?", - [OCOMMA] = ",", - [OLABEL] = "L%d\n", - [ODEFAULT] = "\tf\tL%d\n", - [OBSWITCH] = "\ts", - [OESWITCH] = "\tt\tL%d\n", - [OCASE] = "\tv\tL%d", - [OJUMP] = "\tj\tL%d\n", - [OBRANCH] = "\ty\tL%d", - [OEFUN] = "}\n", - [OELOOP] = "\tb\n", - [OBLOOP] = "\te\n", - [ORET] = "\th", - [OPAR] = "p", - [OCALL] = "c", - [OCALLE] = "z", - [OFIELD] = "." -}; - -void (*opcode[])(int, void *) = { - [OADD] = emitbin, - [OSUB] = emitbin, - [OMUL] = emitbin, - [OINC] = emitbin, - [ODEC] = emitbin, - [OPTR] = emitbin, - [OMOD] = emitbin, - [ODIV] = emitbin, - [OSHL] = emitbin, - [OSHR] = emitbin, - [OLT] = emitbin, - [OGT] = emitbin, - [OGE] = emitbin, - [OLE] = emitbin, - [OEQ] = emitbin, - [ONE] = emitbin, - [OBAND] = emitbin, - [OBXOR] = emitbin, - [OBOR] = emitbin, - [OASSIGN] = emitbin, - [OA_MUL] = emitbin, - [OA_DIV] = emitbin, - [OA_MOD] = emitbin, - [OA_ADD] = emitbin, - [OA_SUB] = emitbin, - [OA_SHL] = emitbin, - [OA_SHR] = emitbin, - [OA_AND] = emitbin, - [OA_XOR] = emitbin, - [OA_OR] = emitbin, - [OADDR] = emitbin, - [OSNEG] = emitbin, - [ONEG] = emitbin, - [OCPL] = emitbin, - [OAND] = emitbin, - [OOR] = emitbin, - [OCOMMA] = emitbin, - [OCAST] = emitcast, - [OSYM] = emitsym, - [OASK] = emitbin, - [OCOLON] = emitbin, - [OFIELD]= emitbin, - [OEXPR] = emitexp, - [OLABEL] = emitsymid, - [ODEFAULT] = emitsymid, - [OCASE] = emitsymid, - [OJUMP] = emitsymid, - [OBRANCH] = emitsymid, - [OEFUN] = emittext, - [OELOOP] = emittext, - [OBLOOP] = emittext, - [OFUN] = emitfun, - [ORET] = emittext, - [ODECL] = emitdcl, - [OBSWITCH] = emittext, - [OESWITCH] = emitsymid, - [OPAR] = emitbin, - [OCALL] = emitbin, - [OCALLE] = emitbin, - [OINIT] = emitinit, - [OBUILTIN] = emitbuilt, - [OTYP] = emittype, -}; - -static FILE *outfp; - -void -icode(void) -{ - outfp = stdout; -} - -void -freetree(Node *np) -{ - if (!np) - return; - freetree(np->left); - freetree(np->right); - free(np); -} - -static void -emitnode(Node *np) -{ - if (np) - (*opcode[np->op])(np->op, np); -} - -void -prtree(Node *np) -{ - outfp = stderr; - fputs("DBG prtree", outfp); - emitnode(np); - putc('\n', outfp); - outfp = stdout; -} - -void -emit(int op, void *arg) -{ - extern int failure; - - if (failure || onlycpp || onlyheader) - return; - (*opcode[op])(op, arg); -} - -static void -emitvar(Symbol *sym) -{ - int c; - short flags = sym->flags; - - if (flags & SLOCAL) - c = 'T'; - else if (flags & SPRIVATE) - c = 'Y'; - else if (flags & SGLOBAL) - c = 'G'; - else if (flags & SREGISTER) - c = 'R'; - else if (flags & SFIELD) - c = 'M'; - else if (flags & SEXTERN) - c = 'X'; - else - c = 'A'; - fprintf(outfp, "%c%u", c, sym->id); -} - -static void -emitconst(Node *np) -{ - Symbol *sym = np->sym; - Type *tp = np->type; - TUINT u; - - switch (tp->op) { - case PTR: - case INT: - case ENUM: - u = (tp->prop & TSIGNED) ? (TUINT) sym->u.i : sym->u.u; - fprintf(outfp, - "#%c%llX", - np->type->letter, - (long long) u & ones(tp->size)); - break; - default: - abort(); - } -} - -static void -emitsym(int op, void *arg) -{ - Node *np = arg; - - if ((np->sym->flags & SINITLST) == 0) { - /* - * When we have a compound literal we are going - * to call to emitnode for every element of it, - * and it means that we will have two '\t' - * for the first element - */ - putc('\t', outfp); - } - (np->flags & NCONST) ? emitconst(np) : emitvar(np->sym); -} - -static void -emitletter(Type *tp) -{ - int letter; - - letter = (tp->prop&TELLIPSIS) ? 'E' : tp->letter; - putc(letter, outfp); - switch (tp->op) { - case ARY: - case STRUCT: - case UNION: - fprintf(outfp, "%u", tp->id); - } -} - -static void -emittype(int op, void *arg) -{ - TINT n; - Symbol **sp; - char *tag; - Type *tp = arg; - - if (!(tp->prop & TDEFINED)) - return; - - switch (tp->op) { - case ARY: - emitletter(tp); - putc('\t', outfp); - emitletter(tp->type); - fprintf(outfp, - "\t#%c%llX\n", - sizettype->letter, (long long) tp->n.elem); - return; - case UNION: - case STRUCT: - emitletter(tp); - tag = tp->tag->name; - fprintf(outfp, - "\t\"%s\t#%c%lX\t#%c%X\n", - (tag) ? tag : "", - sizettype->letter, - tp->size, - sizettype->letter, - tp->align); - n = tp->n.elem; - for (sp = tp->p.fields; n-- > 0; ++sp) - emit(ODECL, *sp); - break; - case PTR: - case FTN: - case ENUM: - return; - default: - abort(); - } -} - -static void -emitstring(Symbol *sym, Type *tp) -{ - char *bp, *s, *lim; - int n; - - bp = sym->u.s; - lim = &sym->u.s[tp->n.elem]; - while (bp < lim) { - s = bp; - while (bp < lim && isprint(*bp)) - ++bp; - if ((n = bp - s) > 1) - fprintf(outfp, "\t#\"%.*s\n", n, s); - else - bp = s; - if (bp == lim) - break; - do { - fprintf(outfp, - "\t#%c%02X\n", - chartype->letter, (*bp++) & 0xFF); - } while (bp < lim && !isprint(*bp)); - } -} - -static void -emitdesig(Node *np, Type *tp) -{ - Symbol *sym; - size_t n; /* TODO: This should be SIZET */ - Node *aux; - Type *p; - - if (!np) { - sym = NULL; - } else { - if (!np->sym) - goto emit_expression; - sym = np->sym; - if (sym->flags & SSTRING) { - emitstring(sym, tp); - return; - } - if ((sym->flags & SINITLST) == 0) - goto emit_expression; - } - - switch (tp->op) { - case PTR: - case INT: - case ENUM: - aux = (sym) ? *sym->u.init : convert(constnode(zero), tp, 0); - emitexp(OEXPR, aux); - break; - case UNION: - n = tp->n.elem-1; - aux = (sym) ? sym->u.init[0] : NULL; - emitdesig(aux, aux->type); - break; - case STRUCT: - case ARY: - for (n = 0; n < tp->n.elem; ++n) { - aux = (sym) ? sym->u.init[n] : NULL; - p = (tp->op == ARY) ? tp->type : tp->p.fields[n]->type; - emitdesig(aux, p); - } - break; - default: - abort(); - } - - if (sym) { - free(sym->u.init); - sym->u.init = NULL; - } - freetree(np); - return; - -emit_expression: - emitexp(OEXPR, np); -} - -static void -emitinit(int op, void *arg) -{ - Node *np = arg; - - fputs("\t(\n", outfp); - emitdesig(np, np->type); - fputs(")\n", outfp); -} - -static void -emitdcl(int op, void *arg) -{ - Symbol *sym = arg; - - if (sym->flags & SEMITTED) - return; - emitvar(sym); - putc('\t', outfp); - if (sym->type->op == FTN) { - emitletter(sym->type->type); - putc('\t', outfp); - } - emitletter(sym->type); - fprintf(outfp, "\t\"%s", (sym->name) ? sym->name : ""); - if (sym->flags & SFIELD) - fprintf(outfp, "\t#%c%llX", sizettype->letter, sym->u.i); - sym->flags |= SEMITTED; - if ((sym->flags & SHASINIT) == 0) - putc('\n', outfp); -} - -static void -emitcast(int op, void *arg) -{ - Node *np = arg, *lp = np->left; - - emitnode(lp); - if (np->type != voidtype) - fprintf(outfp, "\tg%c", np->type->letter); -} - -static void -emitbin(int op, void *arg) -{ - Node *np = arg; - char *s; - - emitnode(np->left); - emitnode(np->right); - if ((s = optxt[op]) != NULL) { /* do not print in OCOLON case */ - fprintf(outfp, "\t%s", s); - emitletter(np->type); - } -} - -static void -emitbuilt(int op, void *arg) -{ - Node *np = arg; - - emitnode(np->left); - emitnode(np->right); - fprintf(outfp, "\t\"%s\tm", np->sym->name); - emitletter(np->type); -} - - -static void -emitexp(int op, void *arg) -{ - Node *np = arg; - - emitnode(np); - putc('\n', outfp); - freetree(np); -} - -static void -emitfun(int op, void *arg) -{ - Symbol *sym = arg, **sp; - - emitdcl(op, arg); - fputs("{\n", outfp); - - for (sp = sym->u.pars; sp && *sp; ++sp) - emit(ODECL, *sp); - fputs("\\\n", outfp); -} - -static void -emittext(int op, void *arg) -{ - fputs(optxt[op], outfp); -} - -static void -emitsymid(int op, void *arg) -{ - Symbol *sym = arg; - fprintf(outfp, optxt[op], sym->id); -} - -Node * -node(int op, Type *tp, Node *lp, Node *rp) -{ - Node *np; - - np = xmalloc(sizeof(*np)); - np->op = op; - np->type = tp; - np->sym = NULL; - np->flags = 0; - np->left = lp; - np->right = rp; - - if (lp) - np->flags |= lp->flags & NEFFECT; - if (rp) - np->flags |= rp->flags & NEFFECT; - return np; -} - -Node * -varnode(Symbol *sym) -{ - Node *np; - Type *tp = sym->type; - - np = node(OSYM, sym->type, NULL, NULL); - np->type = sym->type; - np->flags = (tp->op != FTN && tp->op != ARY) ? NLVAL : 0; - np->sym = sym; - return np; -} - -Node * -constnode(Symbol *sym) -{ - Node *np; - - np = node(OSYM, sym->type, NULL, NULL); - np->type = sym->type; - np->flags = NCONST; - np->sym = sym; - return np; -} - -Node * -sizeofnode(Type *tp) -{ - Symbol *sym; - - sym = newsym(NS_IDEN, NULL); - sym->type = sizettype; - sym->u.i = tp->size; - return constnode(sym); -} diff --git a/cc1/cpp.c b/cc1/cpp.c @@ -1,839 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/cpp.c"; -#include <ctype.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#include <cstd.h> -#include "../inc/scc.h" -#include "cc1.h" - -static char *argp, *macroname; -static unsigned arglen; -static unsigned ncmdlines; -static Symbol *symline, *symfile; -static unsigned char ifstatus[NR_COND]; -static int cppoff; -static struct items dirinclude; - -unsigned cppctx; -int disexpand; - -void -defdefine(char *macro, char *val, char *source) -{ - char *def, *fmt = "#define %s %s\n"; - Symbol dummy = {.flags = SDECLARED}; - - if (!val) - val = ""; - def = xmalloc(strlen(fmt) + strlen(macro) + strlen(val)); - - sprintf(def, fmt, macro, val); - lineno = ++ncmdlines; - addinput(source, &dummy, def); - cpp(); - delinput(); -} - -void -undefmacro(char *s) -{ - killsym(lookup(NS_CPP, s, NOALLOC)); -} - -void -icpp(void) -{ - static char sdate[14], stime[11]; - struct tm *tm; - time_t t; - static char **bp, *list[] = { - "__STDC__", - "__STDC_HOSTED__", - "__SCC__", - NULL - }; - static struct keyword keys[] = { - {"define", DEFINE, DEFINE}, - {"include", INCLUDE, INCLUDE}, - {"line", LINE, LINE}, - {"ifdef", IFDEF, IFDEF}, - {"if", IF, IF}, - {"elif", ELIF, ELIF}, - {"else", ELSE, ELSE}, - {"ifndef", IFNDEF, IFNDEF}, - {"endif", ENDIF, ENDIF}, - {"undef", UNDEF, UNDEF}, - {"pragma", PRAGMA, PRAGMA}, - {"error", ERROR, ERROR}, - {NULL, 0, 0} - }; - - keywords(keys, NS_CPPCLAUSES); - - t = time(NULL); - tm = localtime(&t); - strftime(sdate, sizeof(sdate), "\"%b %d %Y\"", tm); - strftime(stime, sizeof(stime), "\"%H:%M:%S\"", tm); - defdefine("__DATE__", sdate, "built-in"); - defdefine("__TIME__", stime, "built-in"); - defdefine("__STDC_VERSION__", STDC_VERSION, "built-in"); - defdefine("__LINE__", NULL, "built-in"); - defdefine("__FILE__", NULL, "built-in"); - - symline = lookup(NS_CPP, "__LINE__", ALLOC); - symfile = lookup(NS_CPP, "__FILE__", ALLOC); - - for (bp = list; *bp; ++bp) - defdefine(*bp, "1", "built-in"); - - ncmdlines = 0; -} - -static void -nextcpp(void) -{ - next(); - if (yytoken == EOFTOK) - error("unterminated argument list invoking macro \"%s\"", - macroname); - if (yylen + 1 > arglen) - error("argument overflow invoking macro \"%s\"", - macroname); - if (yytoken == IDEN) - yylval.sym->flags |= SUSED; - memcpy(argp, yytext, yylen); - argp += yylen; - *argp++ = ' '; - arglen -= yylen + 1; -} - -static void -paren(void) -{ - for (;;) { - nextcpp(); - switch (yytoken) { - case ')': - return; - case '(': - paren(); - break; - } - } -} - -static void -parameter(void) -{ - for (;;) { - nextcpp(); - switch (yytoken) { - case ')': - case ',': - argp -= 3; /* remove " , " or " ) "*/ - *argp++ = '\0'; - return; - case '(': - paren(); - break; - } - } -} - -static int -parsepars(char *buffer, char **listp, int nargs) -{ - int n; - - if (nargs == -1) - return -1; - if (ahead() != '(' && nargs > 0) - return 0; - - disexpand = 1; - next(); - n = 0; - argp = buffer; - arglen = INPUTSIZ; - if (ahead() == ')') { - next(); - } else { - do { - *listp++ = argp; - parameter(); - } while (++n < NR_MACROARG && yytoken == ','); - } - if (yytoken != ')') - error("incorrect macro function-alike invocation"); - disexpand = 0; - - if (n == NR_MACROARG) - error("too many parameters in macro \"%s\"", macroname); - if (n != nargs) { - error("macro \"%s\" received %d arguments, but it takes %d", - macroname, n, nargs); - } - - return 1; -} - -static size_t -copymacro(char *buffer, char *s, size_t bufsiz, char *arglist[]) -{ - int delim, prevc, c; - char *p, *arg, *bp = buffer; - size_t size; - - for (prevc = '\0'; c = *s; prevc = c, ++s) { - switch (c) { - case '$': - while (bp[-1] == ' ') - --bp, ++bufsiz; - while (s[1] == ' ') - ++s; - case '#': - break; - case '\'': - delim = '\''; - goto search_delim; - case '\"': - delim = '"'; - search_delim: - for (p = s; *++s != delim; ) - ; - size = s - p + 1; - if (size > bufsiz) - goto expansion_too_long; - memcpy(bp, p, size); - bufsiz -= size; - bp += size; - break; - case '@': - if (prevc == '#') - bufsiz -= 2; - arg = arglist[atoi(++s)]; - size = strlen(arg); - if (size > bufsiz) - goto expansion_too_long; - if (prevc == '#') - *bp++ = '"'; - memcpy(bp, arg, size); - bp += size; - if (prevc == '#') - *bp++ = '"'; - bufsiz -= size; - s += 2; - break; - default: - if (bufsiz-- == 0) - goto expansion_too_long; - *bp++ = c; - break; - } - } - *bp = '\0'; - - return bp - buffer; - -expansion_too_long: - error("macro expansion of \"%s\" too long", macroname); -} - -int -expand(char *begin, Symbol *sym) -{ - size_t elen; - int n, i; - char *s = sym->u.s; - char *arglist[NR_MACROARG], arguments[INPUTSIZ], buffer[INPUTSIZ]; - - macroname = sym->name; - if (sym == symfile) { - elen = sprintf(buffer, "\"%s\" ", filenam); - goto substitute; - } - if (sym == symline) { - elen = sprintf(buffer, "%d ", lineno); - goto substitute; - } - if (!s) - return 1; - - n = atoi(s); - if (!parsepars(arguments, arglist, atoi(s))) - return 0; - for (i = 0; i < n; ++i) - DBG("MACRO par%d:%s", i, arglist[i]); - - elen = copymacro(buffer, s+3, INPUTSIZ-1, arglist); - -substitute: - DBG("MACRO '%s' expanded to :'%s'", macroname, buffer); - buffer[elen] = '\0'; - addinput(filenam, sym, xstrdup(buffer)); - - return 1; -} - -static int -getpars(Symbol *args[NR_MACROARG]) -{ - int n, c; - Symbol *sym; - - c = *input->p; - next(); - if (c != '(') - return -1; - next(); /* skip the '(' */ - if (accept(')')) - return 0; - - n = 0; - do { - if (n == NR_MACROARG) { - cpperror("too many parameters in macro"); - return NR_MACROARG; - } - if (accept(ELLIPSIS)) { - args[n++] = NULL; - break; - } - if (yytoken != IDEN) { - cpperror("macro arguments must be identifiers"); - return NR_MACROARG; - } - sym = install(NS_IDEN, yylval.sym); - sym->flags |= SUSED; - args[n++] = sym; - next(); - } while (accept(',')); - expect(')'); - - return n; -} - -static int -getdefs(Symbol *args[NR_MACROARG], int nargs, char *bp, size_t bufsiz) -{ - Symbol **argp; - size_t len; - int prevc = 0, ispar; - - if (yytoken == '$') { - cpperror("'##' cannot appear at either ends of a macro expansion"); - return 0; - } - - for (;;) { - ispar = 0; - if (yytoken == IDEN && nargs >= 0) { - for (argp = args; argp < &args[nargs]; ++argp) { - if (*argp == yylval.sym) - break; - } - if (argp != &args[nargs]) { - sprintf(yytext, "@%02d@", (int) (argp - args)); - ispar = 1; - } - } - if (prevc == '#' && !ispar) { - cpperror("'#' is not followed by a macro parameter"); - return 0; - } - if (yytoken == '\n') - break; - - if ((len = strlen(yytext)) >= bufsiz) { - cpperror("macro too long"); - return 0; - } - if (yytoken == '$') { - *bp++ = '$'; - --bufsiz; - } else { - memcpy(bp, yytext, len); - bp += len; - bufsiz -= len; - } - if ((prevc = yytoken) != '#') { - *bp++ = ' '; - --bufsiz; - } - next(); - } - *bp = '\0'; - return 1; -} - -static void -define(void) -{ - Symbol *sym,*args[NR_MACROARG]; - char buff[LINESIZ+1]; - int n; - - if (cppoff) - return; - - namespace = NS_CPP; - next(); - - if (yytoken != IDEN) { - cpperror("macro names must be identifiers"); - return; - } - sym = yylval.sym; - if (sym->flags & SDECLARED) { - warn("'%s' redefined", yytext); - free(sym->u.s); - } else { - sym = install(NS_CPP, sym); - sym->flags |= SDECLARED|SSTRING; - } - - namespace = NS_IDEN; /* Avoid polution in NS_CPP */ - if ((n = getpars(args)) == NR_MACROARG) - goto delete; - if (n > 0 && !args[n-1]) /* it is a variadic function */ - --n; - sprintf(buff, "%02d#", n); - if (!getdefs(args, n, buff+3, LINESIZ-3)) - goto delete; - sym->u.s = xstrdup(buff); - DBG("MACRO '%s' defined as '%s'", sym->name, buff); - return; - -delete: - killsym(sym); -} - -void -incdir(char *dir) -{ - if (!dir || *dir == '\0') - die("cc1: incorrect -I flag"); - newitem(&dirinclude, dir); -} - -static int -includefile(char *dir, char *file, size_t filelen) -{ - size_t dirlen; - char path[FILENAME_MAX]; - - if (!dir) { - dirlen = 0; - if (filelen > FILENAME_MAX-1) - return 0; - } else { - dirlen = strlen(dir); - if (dirlen + filelen > FILENAME_MAX-2) - return 0; - memcpy(path, dir, dirlen); - if (dir[dirlen-1] != '/') - path[dirlen++] = '/'; - } - memcpy(path+dirlen, file, filelen); - path[dirlen + filelen] = '\0'; - - addinput(path, NULL, NULL); - return 1; -} - -static char * -cwd(char *buf) -{ - char *p, *s = filenam; - size_t len; - - if ((p = strrchr(s, '/')) == NULL) - return NULL; - if ((len = p - s) >= FILENAME_MAX) - die("cc1: current work directory too long"); - memcpy(buf, s, len); - buf[len] = '\0'; - return buf; -} - -static void -include(void) -{ - char dir[FILENAME_MAX], file[FILENAME_MAX], *p, **bp; - size_t filelen; - int n; - - if (cppoff) - return; - - namespace = NS_IDEN; - next(); - - switch (*yytext) { - case '<': - if ((p = strchr(input->begin, '>')) == NULL || p[-1] == '<') - goto bad_include; - filelen = p - input->begin; - if (filelen >= FILENAME_MAX) - goto too_long; - memcpy(file, input->begin, filelen); - file[filelen] = '\0'; - - input->begin = input->p = p+1; - if (next() != '\n') - goto trailing_characters; - - break; - case '"': - if (yylen < 3) - goto bad_include; - filelen = yylen-2; - if (filelen >= FILENAME_MAX) - goto too_long; - memcpy(file, yytext+1, filelen); - file[filelen] = '\0'; - - if (next() != '\n') - goto trailing_characters; - - if (includefile(cwd(dir), file, filelen)) - goto its_done; - break; - default: - goto bad_include; - } - - n = dirinclude.n; - for (bp = dirinclude.s; n--; ++bp) { - if (includefile(*bp, file, filelen)) - goto its_done; - } - cpperror("included file '%s' not found", file); - -its_done: - return; - -trailing_characters: - cpperror("trailing characters after preprocessor directive"); - return; - -too_long: - cpperror("too long file name in #include"); - return; - -bad_include: - cpperror("#include expects \"FILENAME\" or <FILENAME>"); - return; -} - -static void -line(void) -{ - long n; - char *endp, *fname; - - if (cppoff) - return; - - disexpand = 0; - next(); - n = strtol(yytext, &endp, 10); - if (n <= 0 || n > USHRT_MAX || *endp != '\0') { - cpperror("first parameter of #line is not a positive integer"); - return; - } - - next(); - if (yytoken == '\n') { - fname = NULL; - } else { - if (*yytext != '\"' || yylen == 1) { - cpperror("second parameter of #line is not a valid filename"); - return; - } - fname = yylval.sym->u.s; - } - setloc(fname, n - 1); - if (yytoken != '\n') - next(); -} - -static void -pragma(void) -{ - if (cppoff) - return; - next(); - warn("ignoring pragma '%s'", yytext); - *input->p = '\0'; - next(); -} - -static void -usererr(void) -{ - if (cppoff) - return; - cpperror("#error %s", input->p); - *input->p = '\0'; - next(); -} - -static void -ifclause(int negate, int isifdef) -{ - Symbol *sym; - unsigned n; - int status; - Node *expr; - - if (cppctx == NR_COND-1) - error("too many nesting levels of conditional inclusion"); - - n = cppctx++; - namespace = NS_CPP; - next(); - - if (isifdef) { - if (yytoken != IDEN) { - cpperror("no macro name given in #%s directive", - (negate) ? "ifndef" : "ifdef"); - return; - } - sym = yylval.sym; - next(); - status = (sym->flags & SDECLARED) != 0; - if (!status) - killsym(sym); - } else { - /* TODO: catch recovery here */ - if ((expr = constexpr()) == NULL) { - cpperror("parameter of #if is not an integer constant expression"); - return; - } - status = expr->sym->u.i != 0; - freetree(expr); - } - - if (negate) - status = !status; - if ((ifstatus[n] = status) == 0) - ++cppoff; -} - -static void -cppif(void) -{ - disexpand = 0; - ifclause(0, 0); -} - -static void -ifdef(void) -{ - ifclause(0, 1); -} - -static void -ifndef(void) -{ - ifclause(1, 1); -} - -static void -elseclause(void) -{ - int status; - - if (cppctx == 0) { - cpperror("#else without #ifdef/ifndef"); - return; - } - - status = ifstatus[cppctx-1]; - ifstatus[cppctx-1] = !status; - cppoff += (status) ? 1 : -1; -} - -static void -cppelse(void) -{ - elseclause(); - next(); -} - -static void -elif(void) -{ - elseclause(); - if (ifstatus[cppctx-1]) { - --cppctx; - cppif(); - } -} - -static void -endif(void) -{ - if (cppctx == 0) - error("#endif without #if"); - if (!ifstatus[--cppctx]) - --cppoff; - next(); -} - -static void -undef(void) -{ - if (cppoff) - return; - - namespace = NS_CPP; - next(); - if (yytoken != IDEN) { - error("no macro name given in #undef directive"); - return; - } - killsym(yylval.sym); - next(); -} - -int -cpp(void) -{ - static struct { - unsigned char token; - void (*fun)(void); - } *bp, clauses [] = { - {DEFINE, define}, - {INCLUDE, include}, - {LINE, line}, - {IFDEF, ifdef}, - {IF, cppif}, - {ELIF, elif}, - {IFNDEF, ifndef}, - {ELSE, cppelse}, - {ENDIF, endif}, - {UNDEF, undef}, - {PRAGMA, pragma}, - {ERROR, usererr}, - {0, NULL} - }; - int ns; - char *p; - - for (p = input->p; isspace(*p); ++p) - ; - - if (*p != '#') - return cppoff; - input->p = p+1; - - disexpand = 1; - lexmode = CPPMODE; - ns = namespace; - namespace = NS_CPPCLAUSES; - next(); - namespace = NS_IDEN; - - for (bp = clauses; bp->token && bp->token != yytoken; ++bp) - ; - if (!bp->token) { - errorp("incorrect preprocessor directive '%s'", yytext); - goto error; - } - - DBG("CPP %s", yytext); - - pushctx(); /* create a new context to avoid polish */ - (*bp->fun)(); /* the current context, and to get all */ - popctx(); /* the symbols freed at the end */ - - /* - * #include changes the content of input->line, so the correctness - * of the line must be checked in the own include(), and we have - * to skip this tests. For the same reason include() is the only - * function which does not prepare the next token - */ - if (yytoken != '\n' && !cppoff && bp->token != INCLUDE) - errorp("trailing characters after preprocessor directive"); - -error: - disexpand = 0; - lexmode = CCMODE; - namespace = ns; - - return 1; -} - -void -ppragmaln(void) -{ - static char file[FILENAME_MAX]; - static unsigned nline; - char *s; - - putchar('\n'); - if (strcmp(file, filenam)) { - strcpy(file, filenam); - s = "#line %u \"%s\"\n"; - } else if (nline+1 != lineno) { - s = "#line %u\n"; - } else { - s = ""; - } - nline = lineno; - printf(s, nline, file); -} - -void -outcpp(void) -{ - int c; - char *s, *t; - - for (next(); yytoken != EOFTOK; next()) { - if (onlyheader) - continue; - if (yytoken != STRING) { - printf("%s ", yytext); - continue; - } - for (s = yytext; c = *s; ++s) { - switch (c) { - case '\n': - t = "\\n"; - goto print_str; - case '\v': - t = "\\v"; - goto print_str; - case '\b': - t = "\\b"; - goto print_str; - case '\t': - t = "\\t"; - goto print_str; - case '\a': - t = "\\a"; - print_str: - fputs(t, stdout); - break; - case '\\': - putchar('\\'); - default: - if (!isprint(c)) - printf("\\x%x", c); - else - putchar(c); - break; - } - } - putchar(' '); - } - putchar('\n'); -} - diff --git a/cc1/decl.c b/cc1/decl.c @@ -1,967 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/decl.c"; -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> - -#include <cstd.h> -#include "../inc/scc.h" -#include "cc1.h" - -#define NOSCLASS 0 - -#define NOREP 0 -#define REP 1 -#define QUIET 1 -#define NOQUIET 0 - -#define NR_DCL_TYP (NR_DECLARATORS+NR_FUNPARAM) -#define NR_DCL_SYM (NR_DECLARATORS+NR_FUNPARAM+1) - -struct declarators { - unsigned nr; - unsigned ns; - struct decl *dcl; - unsigned nr_types; - Type **tpars; - Symbol **pars; - struct declarator { - unsigned char op; - TINT nelem; - Symbol *sym; - Type **tpars; - Symbol **pars; - } d [NR_DECLARATORS]; -}; - -struct decl { - unsigned ns; - int sclass; - int qualifier; - Symbol *sym; - Type *type; - Type *parent; - Symbol **pars; - Symbol *bufpars[NR_DCL_SYM]; - Type *buftpars[NR_DCL_TYP]; -}; - - -static void -endfundcl(Type *tp, Symbol **pars) -{ - if (tp->prop&TK_R && *pars) - warn("parameter names (without types) in function declaration"); - /* - * avoid non used warnings in prototypes - */ - while (*pars) - (*pars++)->flags |= SUSED; - popctx(); -} - -static void -push(struct declarators *dp, int op, ...) -{ - va_list va; - unsigned n; - struct declarator *p; - - va_start(va, op); - if ((n = dp->nr++) == NR_DECLARATORS) - error("too many declarators"); - - p = &dp->d[n]; - p->op = op; - p->tpars = NULL; - - switch (op) { - case ARY: - p->nelem = va_arg(va, TINT); - break; - case KRFTN: - case FTN: - p->nelem = va_arg(va, unsigned); - p->tpars = va_arg(va, Type **); - p->pars = va_arg(va, Symbol **); - break; - case IDEN: - p->sym = va_arg(va, Symbol *); - break; - } - va_end(va); -} - -static int -pop(struct declarators *dp, struct decl *dcl) -{ - struct declarator *p; - - if (dp->nr == 0) - return 0; - - p = &dp->d[--dp->nr]; - if (p->op == IDEN) { - dcl->sym = p->sym; - return 1; - } - - if (dcl->type->op == FTN) - endfundcl(dcl->type, dcl->pars); - dcl->pars = p->pars; - - dcl->type = mktype(dcl->type, p->op, p->nelem, p->tpars); - return 1; -} - -static void -arydcl(struct declarators *dp) -{ - Node *np = NULL; - TINT n = 0; - - expect('['); - if (yytoken != ']') { - if ((np = constexpr()) == NULL) { - errorp("invalid storage size"); - } else { - if ((n = np->sym->u.i) <= 0) { - errorp("array size is not a positive number"); - n = 1; - } - freetree(np); - } - } - expect(']'); - - push(dp, ARY, n); -} - -static int -empty(Symbol *sym, Type *tp, int param) -{ - if (!sym->name) { - sym->type = tp; - switch (tp->op) { - default: - /* warn if it is not a parameter */ - if (!param) - warn("empty declaration"); - case STRUCT: - case UNION: - case ENUM: - return 1; - } - } - return 0; -} - -static void -bad_storage(Type *tp, char *name) -{ - if (tp->op != FTN) - errorp("incorrect storage class for file-scope declaration"); - else - errorp("invalid storage class for function '%s'", name); -} - -static Symbol * -redcl(Symbol *sym, Type *tp, int sclass) -{ - int flags; - char *name = sym->name; - - if (!eqtype(sym->type, tp, 1)) { - errorp("conflicting types for '%s'", name); - return sym; - } - - if (sym->token == TYPEIDEN && sclass != TYPEDEF || - sym->token != TYPEIDEN && sclass == TYPEDEF) { - goto redeclaration; - } - if (curctx != GLOBALCTX && tp->op != FTN) { - /* is it the redeclaration of a local variable? */ - if ((sym->flags & SEXTERN) && sclass == EXTERN) - return sym; - goto redeclaration; - } - - flags = sym->flags; - switch (sclass) { - case REGISTER: - case AUTO: - bad_storage(tp, name); - break; - case NOSCLASS: - if ((flags & SPRIVATE) == 0) { - if (flags & SEXTERN) - flags &= ~(SEXTERN|SEMITTED); - flags |= SGLOBAL; - break; - } - errorp("non-static declaration of '%s' follows static declaration", - name); - break; - case TYPEDEF: - /* Only C11 allows multiple definitions of a typedef. */ - goto redeclaration; - case EXTERN: - break; - case STATIC: - if ((flags & (SGLOBAL|SEXTERN)) == 0) { - flags |= SPRIVATE; - break; - } - errorp("static declaration of '%s' follows non-static declaration", - name); - break; - } - sym->flags = flags; - - return sym; - -redeclaration: - errorp("redeclaration of '%s'", name); - return sym; -} - -static Symbol * -identifier(struct decl *dcl) -{ - Symbol *sym = dcl->sym; - Type *tp = dcl->type; - int sclass = dcl->sclass; - char *name = sym->name; - - if (empty(sym, tp, 0)) - return sym; - - /* TODO: Add warning about ANSI limits */ - if (!(tp->prop & TDEFINED) && - sclass != EXTERN && sclass != TYPEDEF && - !(tp->op == ARY && yytoken == '=')) { - errorp("declared variable '%s' of incomplete type", name); - } - - if (tp->op == FTN) { - if (sclass == NOSCLASS) - sclass = EXTERN; - if (!strcmp(name, "main") && tp->type != inttype) { - errorp("main shall be defined with a return type of int"); - errorp("please contact __20h__ on irc.freenode.net (#bitreich-en) via IRC"); - } - } - - if (sym->flags & SDECLARED) { - sym = redcl(dcl->sym, tp, sclass); - } else { - int flags = sym->flags | SDECLARED; - - sym->type = tp; - - switch (sclass) { - case REGISTER: - case AUTO: - if (curctx != GLOBALCTX && tp->op != FTN) { - flags |= (sclass == REGISTER) ? SREGISTER : SAUTO; - break; - } - bad_storage(tp, name); - case NOSCLASS: - if (tp->op == FTN) - flags |= SEXTERN; - else - flags |= (curctx == GLOBALCTX) ? SGLOBAL : SAUTO; - break; - case EXTERN: - flags |= SEXTERN; - break; - case STATIC: - flags |= (curctx == GLOBALCTX) ? SPRIVATE : SLOCAL; - break; - case TYPEDEF: - flags |= STYPEDEF; - sym->u.token = sym->token = TYPEIDEN; - break; - } - sym->flags = flags; - } - - if (accept('=')) - initializer(sym, sym->type); - if (!(sym->flags & (SGLOBAL|SEXTERN)) && tp->op != FTN) - sym->flags |= SDEFINED; - if (sym->token == IDEN && tp->op != FTN) - emit(ODECL, sym); - return sym; -} - -static Symbol * -parameter(struct decl *dcl) -{ - Symbol *sym = dcl->sym; - Type *funtp = dcl->parent, *tp = dcl->type; - char *name = sym->name; - int flags; - - flags = 0; - switch (dcl->sclass) { - case STATIC: - case EXTERN: - case AUTO: - errorp("bad storage class in function parameter"); - break; - case REGISTER: - flags |= SREGISTER; - break; - case NOSCLASS: - flags |= SAUTO; - break; - } - - switch (tp->op) { - case VOID: - funtp->n.elem = 1; - if (dcl->sclass) - errorp("void as unique parameter may not be qualified"); - return NULL; - case ARY: - tp = mktype(tp->type, PTR, 0, NULL); - break; - case FTN: - errorp("incorrect function type for a function parameter"); - return NULL; - } - if (!empty(sym, tp, 1)) { - int isdcl = sym->flags&SDECLARED, isk_r = funtp->prop & TK_R; - if (isdcl && !isk_r) { - errorp("redefinition of parameter '%s'", name); - return NULL; - } - if (!isdcl && isk_r) { - errorp("declaration for parameter '%s' but no such parameter", - sym->name); - return NULL; - } - sym->flags |= SDECLARED; - } - - sym->type = tp; - sym->flags &= ~(SAUTO|SREGISTER); - sym->flags |= flags; - return sym; -} - -static Symbol *dodcl(int rep, - Symbol *(*fun)(struct decl *), - unsigned ns, - Type *type); - -static int -krpars(struct declarators *dp) -{ - Symbol *sym; - int toomany = 0; - unsigned npars = 0; - - do { - sym = yylval.sym; - expect(IDEN); - sym->flags |= SAUTO; - if ((sym = install(NS_IDEN, sym)) == NULL) { - errorp("redefinition of parameter '%s'", - yylval.sym->name); - continue; - } - if (npars < NR_FUNPARAM) { - ++npars; - *dp->pars++ = sym; - continue; - } - if (!toomany) - toomany = 1; - } while (accept(',')); - - return toomany; -} - -static unsigned -krfun(struct declarators *dp) -{ - int toomany = 0; - - - if (yytoken != ')') - toomany = krpars(dp); - - if (dp->nr_types == NR_DCL_TYP) { - toomany = 1; - } else { - ++dp->nr_types; - *dp->tpars++ = ellipsistype; - } - - if (toomany) - errorp("too many parameters in function definition"); - return 1; -} - -static unsigned -ansifun(struct declarators *dp) -{ - Symbol *sym; - unsigned npars, ntype, toomany, distoomany, voidpar; - Type type, *tp; - - type.n.elem = 0; - type.prop = 0; - npars = ntype = toomany = distoomany = voidpar = 0; - - do { - if (accept(ELLIPSIS)) { - if (ntype < 1) - errorp("a named argument is requiered before '...'"); - if (yytoken != ')') - errorp("... must be the last parameter"); - sym = NULL; - tp = ellipsistype; - } else if ((sym = dodcl(NOREP, parameter, NS_IDEN, &type)) == NULL) { - if (type.n.elem == 1 && ntype > 1) - voidpar = 1; - sym = NULL; - tp = NULL; - } else { - tp = sym->type; - } - - if (sym) { - if (npars == NR_FUNPARAM) { - toomany = 1; - } else { - npars++; - *dp->pars++ = sym; - } - } - - if (tp) { - if (dp->nr_types == NR_DCL_TYP) { - toomany = 1; - } else { - ntype++; - dp->nr_types++; - *dp->tpars++ = tp; - } - } - - } while (accept(',')); - - if (toomany == 1) - errorp("too many parameters in function definition"); - if (voidpar && ntype > 1) - errorp("'void' must be the only parameter"); - return ntype; -} - -static int -funbody(Symbol *sym, Symbol *pars[]) -{ - Type *tp; - Symbol **bp, *p; - - if (!sym) - return 0; - tp = sym->type; - if (tp->op != FTN) - return 0; - - switch (yytoken) { - case '{': - case TYPE: - case TYPEIDEN: - if (curctx != PARAMCTX) - errorp("nested function declaration"); - if (sym && sym->ns == NS_IDEN) - break; - default: - emit(ODECL, sym); - endfundcl(tp, pars); - return 0; - } - - tp->prop |= TFUNDEF; - curfun = sym; - if (sym->type->prop & TK_R) { - while (yytoken != '{') { - dodcl(REP, parameter, NS_IDEN, sym->type); - expect(';'); - } - for (bp = pars; p = *bp; ++bp) { - if (p->type == NULL) { - warn("type of '%s' defaults to int", p->name); - p->type = inttype; - } - } - } - if (sym->flags & STYPEDEF) - errorp("function definition declared 'typedef'"); - if (sym->flags & SDEFINED) - errorp("redefinition of '%s'", sym->name); - if (sym->flags & SEXTERN) { - sym->flags &= ~SEXTERN; - sym->flags |= SGLOBAL; - } - sym->flags |= SDEFINED; - sym->flags &= ~SEMITTED; - sym->u.pars = pars; - emit(OFUN, sym); - compound(NULL, NULL, NULL); - emit(OEFUN, NULL); - popctx(); - flushtypes(); - curfun = NULL; - return 1; -} - -static void -fundcl(struct declarators *dp) -{ - Type **types = dp->tpars; - unsigned ntypes, typefun; - Symbol **pars = dp->pars; - unsigned (*fun)(struct declarators *); - - pushctx(); - expect('('); - if (yytoken == ')' || yytoken == IDEN) { - typefun = KRFTN; - fun = krfun; - } else { - typefun = FTN; - fun = ansifun; - } - ntypes = (*fun)(dp); - *dp->pars++= NULL; - expect(')'); - - push(dp, typefun, ntypes, types, pars); -} - -static void declarator(struct declarators *dp); - -static void -directdcl(struct declarators *dp) -{ - Symbol *p, *sym; - static int nested; - - if (accept('(')) { - if (nested == NR_SUBTYPE) - error("too many declarators nested by parentheses"); - ++nested; - declarator(dp); - --nested; - expect(')'); - } else { - if (yytoken == IDEN || yytoken == TYPEIDEN) { - sym = yylval.sym; - if (p = install(dp->ns, sym)) { - sym = p; - sym->flags &= ~SDECLARED; - } - next(); - } else { - sym = newsym(dp->ns, NULL); - } - push(dp, IDEN, sym); - } - - for (;;) { - switch (yytoken) { - case '(': fundcl(dp); break; - case '[': arydcl(dp); break; - default: return; - } - } -} - -static void -declarator(struct declarators *dp) -{ - unsigned n; - - for (n = 0; accept('*'); ++n) { - while (accept(TQUALIFIER)) - ; - } - - directdcl(dp); - - while (n--) - push(dp, PTR); -} - -static Type *structdcl(void), *enumdcl(void); - -static Type * -specifier(int *sclass, int *qualifier) -{ - Type *tp = NULL; - unsigned spec, qlf, sign, type, cls, size; - - spec = qlf = sign = type = cls = size = 0; - - for (;;) { - unsigned *p = NULL; - Type *(*dcl)(void) = NULL; - - switch (yytoken) { - case SCLASS: - p = &cls; - break; - case TQUALIFIER: - qlf |= yylval.token; - next(); - continue; - case TYPEIDEN: - if (type) - goto return_type; - tp = yylval.sym->type; - p = &type; - break; - case TYPE: - switch (yylval.token) { - case ENUM: - dcl = enumdcl; - p = &type; - break; - case STRUCT: - case UNION: - dcl = structdcl; - p = &type; - break; - case VA_LIST: - case VOID: - case BOOL: - case CHAR: - case INT: - case FLOAT: - case DOUBLE: - p = &type; - break; - case SIGNED: - case UNSIGNED: - p = &sign; - break; - case LONG: - if (size == LONG) { - yylval.token = LLONG; - size = 0; - } - case SHORT: - p = &size; - break; - } - break; - default: - goto return_type; - } - if (*p) - errorp("invalid type specification"); - *p = yylval.token; - if (dcl) { - if (size || sign) - errorp("invalid type specification"); - tp = (*dcl)(); - goto return_type; - } else { - next(); - } - spec = 1; - } - -return_type: - *sclass = cls; - *qualifier = qlf; - if (!tp) { - if (spec) { - tp = ctype(type, sign, size); - } else { - if (curctx != GLOBALCTX) - unexpected(); - warn("type defaults to 'int' in declaration"); - tp = inttype; - } - } - return tp; -} - -static Symbol * -newtag(void) -{ - Symbol *sym; - int ns, op, tag = yylval.token; - static unsigned tpns = NS_STRUCTS; - - ns = namespace; - namespace = NS_TAG; - next(); - namespace = ns; - - switch (yytoken) { - case IDEN: - case TYPEIDEN: - sym = yylval.sym; - if ((sym->flags & SDECLARED) == 0) - install(NS_TAG, yylval.sym); - next(); - break; - default: - sym = newsym(NS_TAG, NULL); - break; - } - if (!sym->type) { - Type *tp; - - if (tpns == NS_STRUCTS + NR_MAXSTRUCTS) - error("too many tags declared"); - tp = mktype(NULL, tag, 0, NULL); - tp->ns = tpns++; - sym->type = tp; - tp->tag = sym; - DBG("declared tag '%s' with ns = %d\n", - (sym->name) ? sym->name : "anonymous", tp->ns); - } - - if ((op = sym->type->op) != tag && op != INT) - error("'%s' defined as wrong kind of tag", sym->name); - return sym; -} - -static void fieldlist(Type *tp); - -static Type * -structdcl(void) -{ - Symbol *sym; - Type *tp; - static int nested; - int ns; - - sym = newtag(); - tp = sym->type; - - if (!accept('{')) - return tp; - - ns = namespace; - namespace = tp->ns; - - if (tp->prop & TDEFINED && sym->ctx == curctx) - error("redefinition of struct/union '%s'", sym->name); - - if (nested == NR_STRUCT_LEVEL) - error("too many levels of nested structure or union definitions"); - - ++nested; - while (yytoken != '}') { - fieldlist(tp); - } - --nested; - - deftype(tp); - namespace = ns; - expect('}'); - return tp; -} - -static Type * -enumdcl(void) -{ - Type *tp; - Symbol *sym, *tagsym; - int ns, val, toomany; - unsigned nctes; - - ns = namespace; - tagsym = newtag(); - tp = tagsym->type; - - if (!accept('{')) - goto restore_name; - if (tp->prop & TDEFINED) - errorp("redefinition of enumeration '%s'", tagsym->name); - deftype(tp); - namespace = NS_IDEN; - - /* TODO: check incorrect values in val */ - for (nctes = val = 0; yytoken != '}'; ++nctes, ++val) { - if (yytoken != IDEN) - unexpected(); - sym = yylval.sym; - next(); - if (nctes == NR_ENUM_CTES && !toomany) { - errorp("too many enum constants in a single enum"); - toomany = 1; - } - if (accept('=')) { - Node *np = constexpr(); - - if (np == NULL) - errorp("invalid enumeration value"); - else - val = np->sym->u.i; - freetree(np); - } - if ((sym = install(NS_IDEN, sym)) == NULL) { - errorp("'%s' redeclared as different kind of symbol", - yytext); - } else { - sym->u.i = val; - sym->flags |= SCONSTANT; - sym->type = inttype; - } - if (!accept(',')) - break; - } - expect('}'); - -restore_name: - namespace = ns; - return tp; -} - -static Symbol * -type(struct decl *dcl) -{ - Symbol *sym = dcl->sym; - - if (dcl->sclass) - error("class storage in type name"); - if (sym->name) - error("unexpected identifier in type name"); - sym->type = dcl->type; - - return sym; -} - -static Symbol * -field(struct decl *dcl) -{ - static char *anon = "<anonymous>"; - Symbol *sym = dcl->sym; - char *name = (sym->name) ? sym->name : anon; - Type *structp = dcl->parent, *tp = dcl->type; - TINT n = structp->n.elem; - int err = 0; - - if (accept(':')) { - Node *np; - TINT n; - - if ((np = constexpr()) == NULL) { - unexpected(); - n = 0; - } else { - n = np->sym->u.i; - freetree(np); - } - if (n == 0 && name != anon) - errorp("zero width for bit-field '%s'", name); - if (tp != booltype && tp != inttype && tp != uinttype) - errorp("bit-field '%s' has invalid type", name); - if (n < 0) - errorp("negative width in bit-field '%s'", name); - else if (n > tp->size*8) - errorp("width of '%s' exceeds its type", name); - } else if (empty(sym, tp, 0)) { - return sym; - } - - if (tp->op == FTN) { - errorp("invalid type '%s' in struct/union", name); - err = 1; - } - if (dcl->sclass) { - errorp("storage class in struct/union field '%s'", name); - err = 1; - } - if (!(tp->prop & TDEFINED)) { - error("field '%s' has incomplete type", name); - err = 1; - } - if (err) - return sym; - - if (sym->flags & SDECLARED) - error("duplicated member '%s'", name); - sym->flags |= SFIELD|SDECLARED; - sym->type = tp; - - if (n == NR_FIELDS) - error("too many fields in struct/union"); - DBG("New field '%s' in namespace %d\n", name, structp->ns); - structp->p.fields = xrealloc(structp->p.fields, ++n * sizeof(*sym)); - structp->p.fields[n-1] = sym; - structp->n.elem = n; - - return sym; -} - -static Symbol * -dodcl(int rep, Symbol *(*fun)(struct decl *), unsigned ns, Type *parent) -{ - Symbol *sym; - Type *base; - struct decl dcl; - struct declarators stack; - - dcl.ns = ns; - dcl.parent = parent; - base = specifier(&dcl.sclass, &dcl.qualifier); - - do { - dcl.type = base; - stack.nr_types = stack.nr = 0; - stack.tpars = dcl.buftpars; - stack.pars = dcl.bufpars; - stack.dcl = &dcl; - stack.ns = ns; - - declarator(&stack); - - while (pop(&stack, &dcl)) - ; - sym = (*fun)(&dcl); - if (funbody(sym, dcl.pars)) - return sym; - } while (rep && accept(',')); - - return sym; -} - -void -decl(void) -{ - Symbol *sym; - - if (accept(';')) - return; - sym = dodcl(REP, identifier, NS_IDEN, NULL); - if (sym->type->prop & TFUNDEF) - return; - expect(';'); -} - -static void -fieldlist(Type *tp) -{ - if (yytoken != ';') - dodcl(REP, field, tp->ns, tp); - expect(';'); -} - -Type * -typename(void) -{ - return dodcl(NOREP, type, NS_DUMMY, NULL)->type; -} diff --git a/cc1/deps.mk b/cc1/deps.mk @@ -1,45 +0,0 @@ -cpp.c: $(PROJECTDIR)/inc/$(STD)/cstd.h -decl.c: $(PROJECTDIR)/inc/$(STD)/cstd.h -expr.c: $(PROJECTDIR)/inc/$(STD)/cstd.h -init.c: $(PROJECTDIR)/inc/$(STD)/cstd.h -lex.c: $(PROJECTDIR)/inc/$(STD)/cstd.h -stmt.c: $(PROJECTDIR)/inc/$(STD)/cstd.h -symbol.c: $(PROJECTDIR)/inc/$(STD)/cstd.h -types.c: $(PROJECTDIR)/inc/$(STD)/cstd.h - -#deps -builtin.o: ../inc/scc.h -builtin.o: cc1.h -code.o: ../inc/scc.h -code.o: cc1.h -cpp.o: ../inc/scc.h -cpp.o: cc1.h -decl.o: ../inc/scc.h -decl.o: cc1.h -error.o: ../inc/scc.h -error.o: cc1.h -expr.o: ../inc/scc.h -expr.o: cc1.h -fold.o: ../inc/scc.h -fold.o: cc1.h -init.o: ../inc/scc.h -init.o: cc1.h -lex.o: ../inc/scc.h -lex.o: cc1.h -main.o: ../inc/arg.h -main.o: ../inc/scc.h -main.o: cc1.h -stmt.o: ../inc/scc.h -stmt.o: cc1.h -symbol.o: ../inc/scc.h -symbol.o: cc1.h -target/amd64-sysv/arch.o: target/amd64-sysv/../../../inc/scc.h -target/amd64-sysv/arch.o: target/amd64-sysv/../../cc1.h -target/arm64-sysv/arch.o: target/arm64-sysv/../../../inc/scc.h -target/arm64-sysv/arch.o: target/arm64-sysv/../../cc1.h -target/i386-sysv/arch.o: target/i386-sysv/../../../inc/scc.h -target/i386-sysv/arch.o: target/i386-sysv/../../cc1.h -target/z80-scc/arch.o: target/z80-scc/../../../inc/scc.h -target/z80-scc/arch.o: target/z80-scc/../../cc1.h -types.o: ../inc/scc.h -types.o: cc1.h diff --git a/cc1/error.c b/cc1/error.c @@ -1,85 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/error.c"; -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> - -#include "../inc/scc.h" -#include "cc1.h" - -#define MAXERRNUM 10 - -extern int failure; -static unsigned nerrors; - -static void -warn_error(int flag, char *fmt, va_list va) -{ - if (flag == 0) - return; - fprintf(stderr, "%s:%u: %s: ", - filenam, lineno, - (flag < 0) ? "error" : "warning"); - vfprintf(stderr, fmt, va); - putc('\n', stderr); - - if (flag < 0) { - if (!failure) - fclose(stdout); - failure = 1; - if (++nerrors == MAXERRNUM) { - fputs("too many errors\n", stderr); - exit(1); - } - } -} - -void -warn(char *fmt, ...) -{ - extern int warnings; - - va_list va; - va_start(va, fmt); - warn_error(warnings, fmt, va); - va_end(va); -} - -void -error(char *fmt, ...) -{ - va_list va; - - va_start(va, fmt); - warn_error(-1, fmt, va); - va_end(va); - exit(1); - discard(); -} - -void -errorp(char *fmt, ...) -{ - va_list va; - va_start(va, fmt); - warn_error(-1, fmt, va); - va_end(va); -} - -void -cpperror(char *fmt, ...) -{ - va_list va; - va_start(va, fmt); - warn_error(-1, fmt, va); - va_end(va); - - /* discard input until the end of the line */ - *input->p = '\0'; - next(); -} - -void -unexpected(void) -{ - error("unexpected '%s'", yytext); -} diff --git a/cc1/expr.c b/cc1/expr.c @@ -1,1185 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/expr.c"; -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include <cstd.h> -#include "../inc/scc.h" -#include "cc1.h" - -#define XCHG(lp, rp, np) (np = lp, lp = rp, rp = np) - -static Node *xexpr(void), *xassign(void); - -int -cmpnode(Node *np, TUINT val) -{ - Symbol *sym; - Type *tp; - TUINT mask, nodeval; - - if (!np || !(np->flags & NCONST) || !np->sym) - return 0; - sym = np->sym; - tp = sym->type; - - switch (tp->op) { - case PTR: - case INT: - mask = (val > 1) ? ones(np->type->size) : -1; - nodeval = (tp->prop & TSIGNED) ? sym->u.i : sym->u.u; - return (nodeval & mask) == (val & mask); - case FLOAT: - return sym->u.f == val; - } - return 0; -} - -static Node * -promote(Node *np) -{ - Type *tp; - Node *new; - struct limits *lim, *ilim; - - tp = np->type; - - switch (tp->op) { - case ENUM: - case INT: - if (tp->n.rank >= inttype->n.rank) - return np; - lim = getlimits(tp); - ilim = getlimits(inttype); - tp = (lim->max.i <= ilim->max.i) ? inttype : uinttype; - break; - case FLOAT: - /* TODO: Add support for C99 float math */ - tp = doubletype; - break; - default: - abort(); - } - if ((new = convert(np, tp, 1)) != NULL) - return new; - return np; -} - -static void -arithconv(Node **p1, Node **p2) -{ - int to = 0, s1, s2; - unsigned r1, r2; - Type *tp1, *tp2; - Node *np1, *np2; - struct limits *lp1, *lp2; - - np1 = promote(*p1); - np2 = promote(*p2); - - tp1 = np1->type; - tp2 = np2->type; - - if (tp1 == tp2) - goto set_p1_p2; - - s1 = (tp1->prop & TSIGNED) != 0; - r1 = tp1->n.rank; - lp1 = getlimits(tp1); - - s2 = (tp2->prop & TSIGNED) != 0; - r2 = tp2->n.rank; - lp2 = getlimits(tp2); - - if (s1 == s2 || tp1->op == FLOAT || tp2->op == FLOAT) { - to = r1 - r2; - } else if (!s1) { - if (r1 >= r2 || lp1->max.i >= lp2->max.i) - to = 1; - else - to = -1; - } else { - if (r2 >= r1 || lp2->max.i >= lp1->max.i) - to = -1; - else - to = 1; - } - - if (to > 0) - np2 = convert(np2, tp1, 1); - else if (to < 0) - np1 = convert(np1, tp2, 1); - -set_p1_p2: - *p1 = np1; - *p2 = np2; -} - -static int -null(Node *np) -{ - if (np->type != pvoidtype || np->op != OCAST) - return 0; - - np = np->left; - if (np->type != inttype) - return 0; - - return cmpnode(np, 0); -} - -static Node * -chkternary(Node *yes, Node *no) -{ - /* - * FIXME: - * We are ignoring type qualifiers here, - * but the standard has strong rules about this. - * take a look to 6.5.15 - */ - - if (!eqtype(yes->type, no->type, 1)) { - if ((yes->type->prop & TARITH) && (no->type->prop & TARITH)) { - arithconv(&yes, &no); - } else if (yes->type->op != PTR && no->type->op != PTR) { - goto wrong_type; - } else { - /* convert integer 0 to NULL */ - if ((yes->type->prop & TINTEGER) && cmpnode(yes, 0)) - yes = convert(yes, pvoidtype, 0); - if ((no->type->prop & TINTEGER) && cmpnode(no, 0)) - no = convert(no, pvoidtype, 0); - /* - * At this point the type of both should be - * a pointer to something, or we have don't - * compatible types - */ - if (yes->type->op != PTR || no->type->op != PTR) - goto wrong_type; - /* - * If we have a null pointer constant then - * convert to the another type - */ - if (null(yes)) - yes = convert(yes, no->type, 0); - if (null(no)) - no = convert(no, yes->type, 0); - - if (!eqtype(yes->type, no->type, 1)) - goto wrong_type; - } - } - return node(OCOLON, yes->type, yes, no); - -wrong_type: - errorp("type mismatch in conditional expression"); - freetree(yes); - freetree(no); - return constnode(zero); -} - -static void -chklvalue(Node *np) -{ - if (!(np->flags & NLVAL)) - errorp("lvalue required in operation"); - if (np->type == voidtype) - errorp("invalid use of void expression"); -} - -Node * -decay(Node *np) -{ - Node *new; - Type *tp = np->type; - - switch (tp->op) { - case ARY: - tp = tp->type; - if (np->op == OPTR) { - new = np->left; - free(np); - new->type = mktype(tp, PTR, 0, NULL); - return new; - } - case FTN: - new = node(OADDR, mktype(tp, PTR, 0, NULL), np, NULL); - if (np->sym && np->sym->flags & (SGLOBAL|SLOCAL|SPRIVATE)) - new->flags |= NCONST; - return new; - default: - return np; - } -} - -static Node * -integerop(int op, Node *lp, Node *rp) -{ - if (!(lp->type->prop & TINTEGER) || !(rp->type->prop & TINTEGER)) - error("operator requires integer operands"); - arithconv(&lp, &rp); - return node(op, lp->type, lp, rp); -} - -static Node * -integeruop(int op, Node *np) -{ - if (!(np->type->prop & TINTEGER)) - error("unary operator requires integer operand"); - np = promote(np); - return node(op, np->type, np, NULL); -} - -static Node * -numericaluop(int op, Node *np) -{ - if (!(np->type->prop & TARITH)) - error("unary operator requires numerical operand"); - np = promote(np); - return node(op, np->type, np, NULL); -} - -Node * -convert(Node *np, Type *newtp, int iscast) -{ - Type *oldtp = np->type; - - if (eqtype(newtp, oldtp, 0)) - return np; - - switch (oldtp->op) { - case ENUM: - case INT: - case FLOAT: - switch (newtp->op) { - case PTR: - if (oldtp->op == FLOAT || !cmpnode(np, 0) && !iscast) - return NULL; - case INT: - case FLOAT: - case ENUM: - break; - default: - return NULL; - } - break; - case PTR: - switch (newtp->op) { - case ENUM: - case INT: - case VOID: - if (!iscast) - return NULL; - break; - case PTR: - if (eqtype(newtp, oldtp, 1) || - iscast || - newtp == pvoidtype || oldtp == pvoidtype) { - np->type = newtp; - return np; - } - default: - return NULL; - } - break; - default: - return NULL; - } - return node(OCAST, newtp, np, NULL); -} - -static Node * -parithmetic(int op, Node *lp, Node *rp) -{ - Type *tp; - Node *size, *np; - - if (lp->type->op != PTR) - XCHG(lp, rp, np); - - tp = rp->type; - if (tp->op == PTR && !(tp->type->prop & TDEFINED)) - goto incomplete; - tp = lp->type; - if (!(tp->type->prop & TDEFINED)) - goto incomplete; - size = sizeofnode(tp->type); - - if (op == OSUB && BTYPE(rp) == PTR) { - if ((rp = convert(rp, lp->type, 0)) == NULL) - goto incorrect; - lp = node(OSUB, pdifftype, lp, rp); - return node(ODIV, inttype, lp, size); - } - if (!(rp->type->prop & TINTEGER)) - goto incorrect; - - rp = convert(promote(rp), sizettype, 0); - rp = node(OMUL, sizettype, rp, size); - rp = convert(rp, tp, 1); - - return node(op, tp, lp, rp); - -incomplete: - errorp("invalid use of undefined type"); - return lp; -incorrect: - errorp("incorrect arithmetic operands"); - return lp; - -} - -static Node * -arithmetic(int op, Node *lp, Node *rp) -{ - Type *ltp = lp->type, *rtp = rp->type; - - if ((ltp->prop & TARITH) && (rtp->prop & TARITH)) { - arithconv(&lp, &rp); - return node(op, lp->type, lp, rp); - } else if ((ltp->op == PTR || rtp->op == PTR)) { - switch (op) { - case OADD: - case OSUB: - case OA_ADD: - case OA_SUB: - case OINC: - case ODEC: - return parithmetic(op, lp, rp); - } - } - errorp("incorrect arithmetic operands"); -} - -static Node * -pcompare(int op, Node *lp, Node *rp) -{ - Node *np; - - if (lp->type->prop & TINTEGER) - XCHG(lp, rp, np); - else if (eqtype(lp->type, pvoidtype, 1)) - XCHG(lp, rp, np); - - if ((np = convert(rp, lp->type, 0)) != NULL) - rp = np; - else - errorp("incompatible types in comparison"); - return convert(node(op, pvoidtype, lp, rp), inttype, 1); -} - -static Node * -compare(int op, Node *lp, Node *rp) -{ - Type *ltp, *rtp; - - ltp = lp->type; - rtp = rp->type; - - if (ltp->op == PTR || rtp->op == PTR) { - return pcompare(op, rp, lp); - } else if ((ltp->prop & TARITH) && (rtp->prop & TARITH)) { - arithconv(&lp, &rp); - return convert(node(op, lp->type, lp, rp), inttype, 1);; - } else { - errorp("incompatible types in comparison"); - freetree(lp); - freetree(rp); - return constnode(zero); - } -} - -int -negop(int op) -{ - switch (op) { - case OEQ: return ONE; - case ONE: return OEQ; - case OLT: return OGE; - case OGE: return OLT; - case OLE: return OGT; - case OGT: return OLE; - default: abort(); - } - return op; -} - -static Node * -exp2cond(Node *np, int neg) -{ - if (np->type->prop & TAGGREG) { - errorp("used struct/union type value where scalar is required"); - return constnode(zero); - } - switch (np->op) { - case ONEG: - case OOR: - case OAND: - return (neg) ? node(ONEG, inttype, np, NULL) : np; - case OEQ: - case ONE: - case OLT: - case OGE: - case OLE: - case OGT: - if (neg) - np->op = negop(np->op); - return np; - default: - return compare((neg) ? OEQ : ONE, np, constnode(zero)); - } -} - -static Node * -logic(int op, Node *lp, Node *rp) -{ - lp = exp2cond(lp, 0); - rp = exp2cond(rp, 0); - return node(op, inttype, lp, rp); -} - -static Node * -field(Node *np) -{ - Symbol *sym; - - namespace = np->type->ns; - next(); - namespace = NS_IDEN; - - sym = yylval.sym; - if (yytoken != IDEN) - unexpected(); - next(); - - if (!(np->type->prop & TAGGREG)) { - errorp("request for member '%s' in something not a structure or union", - yylval.sym->name); - goto free_np; - } - if ((sym->flags & SDECLARED) == 0) { - errorp("incorrect field in struct/union"); - goto free_np; - } - np = node(OFIELD, sym->type, np, varnode(sym)); - np->flags |= NLVAL; - return np; - -free_np: - freetree(np); - return constnode(zero); -} - -static Node * -content(int op, Node *np) -{ - if (BTYPE(np) != PTR) { - errorp("invalid argument of memory indirection"); - } else { - if (np->op == OADDR) { - Node *new = np->left; - new->type = np->type->type; - free(np); - np = new; - } else { - np = node(op, np->type->type, np, NULL); - } - np->flags |= NLVAL; - } - return np; -} - -static Node * -array(Node *lp, Node *rp) -{ - Type *tp; - Node *np; - - if (!(lp->type->prop & TINTEGER) && !(rp->type->prop & TINTEGER)) - error("array subscript is not an integer"); - np = arithmetic(OADD, lp, rp); - tp = np->type; - if (tp->op != PTR) - errorp("subscripted value is neither array nor pointer"); - return content(OPTR, np); -} - -static Node * -assignop(int op, Node *lp, Node *rp) -{ - if ((rp = convert(rp, lp->type, 0)) == NULL) { - errorp("incompatible types when assigning"); - return lp; - } - - return node(op, lp->type, lp, rp); -} - -static Node * -incdec(Node *np, int op) -{ - Type *tp = np->type; - Node *inc; - - chklvalue(np); - np->flags |= NEFFECT; - - if (!(tp->prop & TDEFINED)) { - errorp("invalid use of undefined type"); - return np; - } else if (tp->op == PTR && !(tp->type->prop & TDEFINED)) { - errorp("%s of pointer to an incomplete type", - (op == OINC || op == OA_ADD) ? "increment" : "decrement"); - return np; - } else if (tp->op == PTR || (tp->prop & TARITH)) { - inc = constnode(one); - } else { - errorp("wrong type argument to increment or decrement"); - return np; - } - return arithmetic(op, np, inc); -} - -static Node * -address(int op, Node *np) -{ - Node *new; - - /* - * ansi c accepts & applied to a function name, and it generates - * a function pointer - */ - if (np->op == OSYM) { - if (np->type->op == FTN) - return decay(np); - if (np->type->op == ARY) - goto dont_check_lvalue; - } - chklvalue(np); - -dont_check_lvalue: - if (np->sym && (np->sym->flags & SREGISTER)) - errorp("address of register variable '%s' requested", yytext); - new = node(op, mktype(np->type, PTR, 0, NULL), np, NULL); - if (np->sym && np->sym->flags & (SGLOBAL|SLOCAL|SPRIVATE)) - new->flags |= NCONST; - return new; -} - -static Node * -negation(int op, Node *np) -{ - if (!(np->type->prop & TARITH) && np->type->op != PTR) { - errorp("invalid argument of unary '!'"); - return constnode(zero); - } - return exp2cond(np, 1); -} - -static Symbol * -notdefined(Symbol *sym) -{ - int isdef; - - if (namespace == NS_CPP && !strcmp(sym->name, "defined")) { - disexpand = 1; - next(); - expect('('); - sym = yylval.sym; - expect(IDEN); - expect(')'); - - isdef = (sym->flags & SDECLARED) != 0; - sym = newsym(NS_IDEN, NULL); - sym->type = inttype; - sym->flags |= SCONSTANT; - sym->u.i = isdef; - disexpand = 0; - return sym; - } - errorp("'%s' undeclared", yytext); - sym->type = inttype; - return install(sym->ns, yylval.sym); -} - -static Symbol * -adjstrings(Symbol *sym) -{ - char *s, *t; - size_t len, n; - Type *tp; - - tp = sym->type; - s = sym->u.s; - for (len = strlen(s);; len += n) { - next(); - if (yytoken != STRING) - break; - t = yylval.sym->u.s; - n = strlen(t); - s = xrealloc(s, len + n + 1); - memcpy(s+len, t, n); - s[len + n] = '\0'; - killsym(yylval.sym); - } - ++len; - if (tp->n.elem != len) { - sym->type = mktype(chartype, ARY, len, NULL); - sym->u.s = s; - } - return sym; -} - -/************************************************************* - * grammar functions * - *************************************************************/ -static Node * -primary(void) -{ - Node *np; - Symbol *sym; - Node *(*fun)(Symbol *); - - sym = yylval.sym; - switch (yytoken) { - case STRING: - np = constnode(adjstrings(sym)); - sym->flags |= SHASINIT; - emit(ODECL, sym); - emit(OINIT, np); - return varnode(sym); - case BUILTIN: - fun = sym->u.fun; - next(); - expect('('); - np = (*fun)(sym); - expect(')'); - - /* do not call to next */ - return np; - case CONSTANT: - np = constnode(sym); - break; - case IDEN: - assert((sym->flags & SCONSTANT) == 0); - if ((sym->flags & SDECLARED) == 0) { - if (namespace == NS_CPP) { - np = constnode(zero); - break; - } - sym = notdefined(sym); - } - sym->flags |= SUSED; - np = varnode(sym); - break; - default: - unexpected(); - } - next(); - - return np; -} - -static Node * -arguments(Node *np) -{ - int toomany, n, op; - Node *par = NULL, *arg; - Type *argtype, **targs, *tp = np->type, *rettype; - - if (tp->op == PTR && tp->type->op == FTN) { - np = content(OPTR, np); - tp = np->type; - } - if (tp->op != FTN) { - targs = (Type *[]) {ellipsistype}; - n = 1; - rettype = inttype; - errorp("function or function pointer expected"); - } else { - targs = tp->p.pars; - n = tp->n.elem; - rettype = tp->type; - } - - expect('('); - if (yytoken == ')') - goto no_pars; - toomany = 0; - - do { - arg = xassign(); - argtype = *targs; - if (argtype == ellipsistype) { - n = 0; - switch (arg->type->op) { - case INT: - arg = promote(arg); - break; - case FLOAT: - if (arg->type == floattype) - arg = convert(arg, doubletype, 1); - break; - } - par = node(OPAR, arg->type, par, arg); - continue; - } - if (--n < 0) { - if (!toomany) - errorp("too many arguments in function call"); - toomany = 1; - continue; - } - ++targs; - if ((arg = convert(arg, argtype, 0)) != NULL) { - par = node(OPAR, arg->type, par, arg); - continue; - } - errorp("incompatible type for argument %d in function call", - tp->n.elem - n + 1); - } while (accept(',')); - -no_pars: - expect(')'); - if (n > 0 && *targs != ellipsistype) - errorp("too few arguments in function call"); - - op = (tp->prop&TELLIPSIS) ? OCALLE : OCALL; - return node(op, rettype, np, par); -} - -static Node *unary(int); - -static Type * -typeof(Node *np) -{ - Type *tp; - - if (np == NULL) - unexpected(); - tp = np->type; - freetree(np); - return tp; -} - -static Type * -sizeexp(void) -{ - Type *tp; - - expect('('); - switch (yytoken) { - case TYPE: - case TYPEIDEN: - tp = typename(); - break; - default: - tp = typeof(unary(0)); - break; - } - expect(')'); - return tp; -} - -static Node * -postfix(Node *lp) -{ - Node *rp; - - for (;;) { - switch (yytoken) { - case '[': - case DEC: - case INC: - case INDIR: - case '.': - case '(': - lp = decay(lp); - switch (yytoken) { - case '[': - next(); - rp = xexpr(); - expect(']'); - lp = array(lp, rp); - break; - case DEC: - case INC: - lp = incdec(lp, (yytoken == INC) ? OINC : ODEC); - next(); - break; - case INDIR: - lp = content(OPTR, lp); - case '.': - lp = field(lp); - break; - case '(': - lp = arguments(lp); - lp->flags |= NEFFECT; - break; - } - break; - default: - return lp; - } - } -} - -static Node * -defined(void) -{ - Symbol *sym; - int paren; - - disexpand = 1; - next(); - paren = accept('('); - if (yytoken != IDEN && yytoken != TYPEIDEN) - cpperror("operator 'defined' requires an identifier"); - if (yytoken == TYPEIDEN || !(yylval.sym->flags & SDECLARED)) - sym = zero; - else - sym = one; - disexpand = 0; - next(); - if (paren) - expect(')'); - return constnode(sym); -} - -static Node *cast(int); - -static Node * -unary(int needdecay) -{ - Node *(*fun)(int, Node *), *np; - int op; - Type *tp; - - switch (yytoken) { - case '!': op = 0; fun = negation; break; - case '+': op = OADD; fun = numericaluop; break; - case '-': op = OSNEG; fun = numericaluop; break; - case '~': op = OCPL; fun = integeruop; break; - case '&': op = OADDR; fun = address; break; - case '*': op = OPTR; fun = content; break; - case SIZEOF: - next(); - tp = (yytoken == '(') ? sizeexp() : typeof(unary(0)); - if (!(tp->prop & TDEFINED)) - errorp("sizeof applied to an incomplete type"); - return sizeofnode(tp); - case INC: - case DEC: - op = (yytoken == INC) ? OA_ADD : OA_SUB; - next(); - np = incdec(unary(1), op); - goto chk_decay; - case IDEN: - case TYPEIDEN: - if (lexmode == CPPMODE && !strcmp(yylval.sym->name, "defined")) - return defined(); - default: - np = postfix(primary()); - goto chk_decay; - } - - next(); - np = (*fun)(op, cast(op != OADDR)); - -chk_decay: - if (needdecay) - np = decay(np); - return np; -} - -static Node * -cast(int needdecay) -{ - Node *lp, *rp; - Type *tp; - static int nested; - - if (!accept('(')) - return unary(needdecay); - - switch (yytoken) { - case TQUALIFIER: - case TYPE: - case TYPEIDEN: - tp = typename(); - expect(')'); - - if (yytoken == '{') - return initlist(tp); - - switch (tp->op) { - case ARY: - error("cast specifies an array type"); - default: - lp = cast(needdecay); - if ((rp = convert(lp, tp, 1)) == NULL) - error("bad type conversion requested"); - rp->flags &= ~NLVAL; - rp->flags |= lp->flags & NLVAL; - } - break; - default: - if (nested == NR_SUBEXPR) - error("too many expressions nested by parentheses"); - ++nested; - rp = xexpr(); - --nested; - expect(')'); - rp = postfix(rp); - break; - } - - return rp; -} - -static Node * -mul(void) -{ - Node *np, *(*fun)(int, Node *, Node *); - int op; - - np = cast(1); - for (;;) { - switch (yytoken) { - case '*': op = OMUL; fun = arithmetic; break; - case '/': op = ODIV; fun = arithmetic; break; - case '%': op = OMOD; fun = integerop; break; - default: return np; - } - next(); - np = (*fun)(op, np, cast(1)); - } -} - -static Node * -add(void) -{ - int op; - Node *np; - - np = mul(); - for (;;) { - switch (yytoken) { - case '+': op = OADD; break; - case '-': op = OSUB; break; - default: return np; - } - next(); - np = arithmetic(op, np, mul()); - } -} - -static Node * -shift(void) -{ - int op; - Node *np; - - np = add(); - for (;;) { - switch (yytoken) { - case SHL: op = OSHL; break; - case SHR: op = OSHR; break; - default: return np; - } - next(); - np = integerop(op, np, add()); - } -} - -static Node * -relational(void) -{ - int op; - Node *np; - - np = shift(); - for (;;) { - switch (yytoken) { - case '<': op = OLT; break; - case '>': op = OGT; break; - case GE: op = OGE; break; - case LE: op = OLE; break; - default: return np; - } - next(); - np = compare(op, np, shift()); - } -} - -static Node * -eq(void) -{ - int op; - Node *np; - - np = relational(); - for (;;) { - switch (yytoken) { - case EQ: op = OEQ; break; - case NE: op = ONE; break; - default: return np; - } - next(); - np = compare(op, np, relational()); - } -} - -static Node * -bit_and(void) -{ - Node *np; - - np = eq(); - while (accept('&')) - np = integerop(OBAND, np, eq()); - return np; -} - -static Node * -bit_xor(void) -{ - Node *np; - - np = bit_and(); - while (accept('^')) - np = integerop(OBXOR, np, bit_and()); - return np; -} - -static Node * -bit_or(void) -{ - Node *np; - - np = bit_xor(); - while (accept('|')) - np = integerop(OBOR, np, bit_xor()); - return np; -} - -static Node * -and(void) -{ - Node *np; - - np = bit_or(); - while (accept(AND)) - np = logic(OAND, np, bit_or()); - return np; -} - -static Node * -or(void) -{ - Node *np; - - np = and(); - while (accept(OR)) - np = logic(OOR, np, and()); - return np; -} - -static Node * -ternary(void) -{ - Node *cond; - - cond = or(); - while (accept('?')) { - Node *ifyes, *ifno, *np; - - cond = exp2cond(cond, 0); - ifyes = xexpr(); - expect(':'); - ifno = ternary(); - np = chkternary(ifyes, ifno); - cond = node(OASK, np->type, cond, np); - } - return cond; -} - -static Node * -xassign(void) -{ - Node *np, *(*fun)(int , Node *, Node *); - int op; - - np = ternary(); - for (;;) { - switch (yytoken) { - case '=': op = OASSIGN; fun = assignop; break; - case MUL_EQ: op = OA_MUL; fun = arithmetic; break; - case DIV_EQ: op = OA_DIV; fun = arithmetic; break; - case MOD_EQ: op = OA_MOD; fun = integerop; break; - case ADD_EQ: op = OA_ADD; fun = arithmetic; break; - case SUB_EQ: op = OA_SUB; fun = arithmetic; break; - case SHL_EQ: op = OA_SHL; fun = integerop; break; - case SHR_EQ: op = OA_SHR; fun = integerop; break; - case AND_EQ: op = OA_AND; fun = integerop; break; - case XOR_EQ: op = OA_XOR; fun = integerop; break; - case OR_EQ: op = OA_OR; fun = integerop; break; - default: return np; - } - chklvalue(np); - np->flags |= NEFFECT; - next(); - np = (fun)(op, np, assign()); - } -} - -static Node * -xexpr(void) -{ - Node *lp, *rp; - - lp = xassign(); - while (accept(',')) { - rp = xassign(); - lp = node(OCOMMA, rp->type, lp, rp); - } - return lp; -} - -Node * -assign(void) -{ - return simplify(xassign()); -} - -Node * -constexpr(void) -{ - Node *np; - - np = ternary(); - if (np && np->type->op == INT) { - np = simplify(convert(np, inttype, 0)); - if (np->flags & NCONST) - return np; - } - freetree(np); - return NULL; -} - -Node * -expr(void) -{ - return simplify(xexpr()); -} - -Node * -condexpr(int neg) -{ - Node *np; - - np = exp2cond(xexpr(), neg); - if (np->flags & NCONST) - warn("conditional expression is constant"); - return simplify(np); -} diff --git a/cc1/fold.c b/cc1/fold.c @@ -1,685 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/fold.c"; -#include <assert.h> -#include <stdlib.h> - -#include "../inc/scc.h" -#include "cc1.h" - - -TUINT -ones(int nbytes) -{ - return (nbytes == 8) ? -1 : ~(-1ull << nbytes * 8); -} - -static int -addi(TINT l, TINT r, Type *tp) -{ - struct limits *lim = getlimits(tp); - TINT max = lim->max.i, min = -lim->min.i; - - if (l < 0 && r < 0 && l >= min - r || - l == 0 || - r == 0 || - l < 0 && r > 0 || - l > 0 && r < 0 || - l > 0 && r > 0 && l <= max - r) { - return 1; - } - warn("overflow in constant expression"); - return 0; -} - -static int -addf(TFLOAT l, TFLOAT r, Type *tp) -{ - struct limits *lim = getlimits(tp); - TFLOAT max = lim->max.f, min = lim->min.f; - - if (l < 0 && r < 0 && l >= min - r || - l == 0 || - r == 0 || - l < 0 && r > 0 || - l > 0 && r < 0 || - l > 0 && r > 0 && l <= max - r) { - return 1; - } - warn("overflow in constant expression"); - return 0; -} - -static int -subi(TINT l, TINT r, Type *tp) -{ - return addi(l, -r, tp); -} - -static int -subf(TFLOAT l, TFLOAT r, Type *tp) -{ - return addf(l, -r, tp); -} - -static int -muli(TINT l, TINT r, Type *tp) -{ - struct limits *lim = getlimits(tp); - TINT max = lim->max.i, min = -lim->min.i; - - if (l > -1 && l <= 1 || - r > -1 && r <= 1 || - l < 0 && r < 0 && -l <= max/-r || - l < 0 && r > 0 && l >= min/r || - l > 0 && r < 0 && r >= min/l || - l > 0 && r > 0 && l <= max/r) { - return 1; - } - warn("overflow in constant expression"); - return 0; -} - -static int -mulf(TFLOAT l, TFLOAT r, Type *tp) -{ - struct limits *lim = getlimits(tp); - TFLOAT max = lim->max.f, min = lim->min.f; - - if (l > -1 && l <= 1 || - r > -1 && r <= 1 || - l < 0 && r < 0 && -l <= max/-r || - l < 0 && r > 0 && l >= min/r || - l > 0 && r < 0 && r >= min/l || - l > 0 && r > 0 && l <= max/r) { - return 1; - } - warn("overflow in constant expression"); - return 0; -} - -static int -divi(TINT l, TINT r, Type *tp) -{ - struct limits *lim = getlimits(tp); - - if (r == 0 || l == -lim->min.i && r == -1) { - warn("overflow in constant expression"); - return 0; - } - return 1; -} - -static int -divf(TFLOAT l, TFLOAT r, Type *tp) -{ - struct limits *lim = getlimits(tp); - - if (l < 0) l = -l; - if (r < 0) r = -r; - - if (r == 0.0 || r < 1.0 && l > lim->max.f * r) { - warn("overflow in constant expression"); - return 0; - } - return 1; -} - -static int -lshi(TINT l, TINT r, Type *tp) -{ - if (r < 0 || r >= tp->size * 8) { - warn("shifting %d bits is undefined", r); - return 0; - } - return muli(l, 1 << r, tp); -} - -static int -rshi(TINT l, TINT r, Type *tp) -{ - if (r < 0 || r >= tp->size * 8) { - warn("shifting %d bits is undefined", r); - return 0; - } - return 1; -} - -static int -foldint(int op, Symbol *res, TINT l, TINT r) -{ - TINT i; - Type *tp = res->type; - int (*validate)(TINT, TINT, Type *tp); - - switch (op) { - case OADD: validate = addi; break; - case OSUB: validate = subi; break; - case OMUL: validate = muli; break; - case ODIV: validate = divi; break; - case OSHL: validate = lshi; break; - case OSHR: validate = rshi; break; - case OMOD: validate = divi; break; - default: validate = NULL; break; - } - - if (validate && !(*validate)(l, r, tp)) - return 0; - - switch (op) { - case OADD: i = l + r; break; - case OSUB: i = l - r; break; - case OMUL: i = l * r; break; - case ODIV: i = l / r; break; - case OMOD: i = l % r; break; - case OSHL: i = l << r; break; - case OSHR: i = l >> r; break; - case OBAND: i = l & r; break; - case OBXOR: i = l ^ r; break; - case OBOR: i = l | r; break; - case OAND: i = l && r; break; - case OOR: i = l || r; break; - case OLT: i = l < r; break; - case OGT: i = l > r; break; - case OGE: i = l >= r; break; - case OLE: i = l <= r; break; - case OEQ: i = l == r; break; - case ONE: i = l != r; break; - case ONEG: i = !l; break; - case OSNEG: i = -l; break; - case OCPL: i = ~l; break; - default: return 0; - } - res->u.i = i; - - DBG("FOLD i l=%lld %d r=%lld = %lld", l, op, r, i); - return 1; -} - -static int -folduint(int op, Symbol *res, TUINT l, TUINT r) -{ - TINT i; - TUINT u; - - switch (op) { - case OADD: u = l + r; break; - case OSUB: u = l - r; break; - case OMUL: u = l * r; break; - case ODIV: u = l / r; break; - case OMOD: u = l % r; break; - case OSHL: u = l << r; break; - case OSHR: u = l >> r; break; - case OBAND: u = l & r; break; - case OBXOR: u = l ^ r; break; - case OBOR: u = l | r; break; - case ONEG: u = !l; break; - case OSNEG: u = -l; break; - case OCPL: u = ~l; break; - case OAND: i = l && r; goto sign; - case OOR: i = l || r; goto sign; - case OLT: i = l < r; goto sign; - case OGT: i = l > r; goto sign; - case OGE: i = l >= r; goto sign; - case OLE: i = l <= r; goto sign; - case OEQ: i = l == r; goto sign; - case ONE: i = l != r; goto sign; - default: return 0; - } - res->u.u = u & ones(res->type->size); - - DBG("FOLD ui l=%llu %d r=%llu = %llu", l, op, r, u); - return 1; - -sign: - res->u.i = i; - - DBG("FOLD sui %llu %d %llu = %llu", l, op, r, i); - return 1; -} - -static int -foldfloat(int op, Symbol *res, TFLOAT l, TFLOAT r) -{ - TFLOAT f; - TINT i; - int (*validate)(TFLOAT, TFLOAT, Type *tp); - - switch (op) { - case OADD: validate = addf; break; - case OSUB: validate = subf; break; - case OMUL: validate = mulf; break; - case ODIV: validate = divf; break; - default: validate = NULL; break; - } - - if (validate && !(*validate)(l, r, res->type)) - return 0; - - switch (op) { - case OADD: f = l + r; break; - case OSUB: f = l - r; break; - case OMUL: f = l * r; break; - case ODIV: f = l / r; break; - case OLT: i = l < r; goto comparison; - case OGT: i = l > r; goto comparison; - case OGE: i = l >= r; goto comparison; - case OLE: i = l <= r; goto comparison; - case OEQ: i = l == r; goto comparison; - case ONE: i = l != r; goto comparison; - default: return 0; - } - res->u.f = f; - - DBG("FOLD f l=%lf %d r=%lf = %lf", l, op, r, f); - return 1; - -comparison: - res->u.i = i; - - DBG("FOLD if l=%lf %d r=%lf = %lld", l, op, r, i); - return 1; -} - -static Node * -foldconst(int type, int op, Type *tp, Symbol *ls, Symbol *rs) -{ - Symbol *sym, aux; - TINT i; - TUINT u; - TFLOAT f; - - aux.type = tp; - switch (type) { - case INT: - i = (rs) ? rs->u.i : 0; - if (!foldint(op, &aux, ls->u.i, i)) - return NULL; - break; - case UNSIGNED: - u = (rs) ? rs->u.u : 0u; - if (!folduint(op, &aux, ls->u.u, u)) - return NULL; - break; - case FLOAT: - f = (rs) ? rs->u.f : 0.0; - if (!foldfloat(op, &aux, ls->u.f, f)) - return NULL; - break; - } - sym = newsym(NS_IDEN, NULL); - sym->flags |= SCONSTANT; - sym->type = tp; - sym->u = aux.u; - return constnode(sym); -} - -static Node * -foldcast(Node *np, Node *l) -{ - TUINT negmask, mask, u; - Type *newtp = np->type, *oldtp = l->type; - Symbol aux, *sym, *osym = l->sym; - - if (!(l->flags & NCONST)) - return np; - - switch (newtp->op) { - case PTR: - case INT: - case ENUM: - switch (oldtp->op) { - case PTR: - case INT: - case ENUM: - u = (oldtp->prop & TSIGNED) ? osym->u.i : osym->u.u; - break; - case FLOAT: - oldtp = newtp; - u = osym->u.f; - break; - default: - return np; - } - mask = ones(newtp->size); - if (newtp->prop & TSIGNED) { - negmask = ~mask; - if (u & (negmask >> 1) & mask) - u |= negmask; - aux.u.i = u; - } else { - aux.u.u = u & mask; - } - break; - case FLOAT: - /* FIXME: The cast can be from another float type */ - aux.u.f = (oldtp->prop & TSIGNED) ? osym->u.i : osym->u.u; - break; - default: - return np; - } - DBG("FOLD cast %c->%c", oldtp->letter, newtp->letter); - freetree(np); - sym = newsym(NS_IDEN, NULL); - sym->flags |= SCONSTANT; - sym->type = newtp; - sym->u = aux.u; - return constnode(sym); -} - -static Node * -foldunary(Node *np, Node *l) -{ - int op = l->op; - Node *aux; - - switch (np->op) { - case ONEG: - if (l->op == ONEG) - break; - return NULL; - case OADD: - DBG("FOLD unary delete %d", np->op); - np->left = NULL; - freetree(np); - return l; - case OCAST: - if (op != OCAST) - return foldcast(np, l); - /* TODO: This is wrong: (float)(int) 7.2 */ - DBG("FOLD unary collapse %d", np->op); - np->left = l->left; - l->left = NULL; - freetree(l); - return np; - case OSNEG: - case OCPL: - if (op != np->op) - return NULL; - break; - case OPTR: - if (op != OADDR || np->type != l->left->type) - return NULL; - break; - case OADDR: - if (op != OPTR) - return NULL; - break; - default: - return NULL; - } - DBG("FOLD unary cancel %d", np->op); - aux = l->left; - l->left = NULL; - freetree(np); - return aux; -} - -static Node * -fold(Node *np) -{ - Symbol *rs, *ls; - Type *optype; - int type; - int op = np->op; - Node *p, *lp = np->left, *rp = np->right; - Type *tp = np->type; - - assert(lp && rp); - if ((op == ODIV || op == OMOD) && cmpnode(rp, 0)) { - warn("division by 0"); - return NULL; - } - /* - * Return if any of the children is no constant, - * or it is a constant generated when - * the address of a static variable is taken - * (when we don't know the physical address so - * we cannot fold it) - */ - if (!rp) { - rs = NULL; - } else { - if (!(rp->flags & NCONST) || !rp->sym) - return NULL; - rs = rp->sym; - } - - if (!(lp->flags & NCONST) || !lp->sym) - return NULL; - optype = lp->type; - ls = lp->sym; - - switch (type = optype->op) { - case ENUM: - case INT: - if (!(optype->prop & TSIGNED)) - type = UNSIGNED; - case PTR: - case FLOAT: - if ((p = foldconst(type, op, tp, ls, rs)) == NULL) - return NULL; - freetree(np); - return p; - default: - return NULL; - } -} - -static void -commutative(Node *np, Node *l, Node *r) -{ - int op = np->op; - - if (r == NULL || r->flags&NCONST || !(l->flags&NCONST)) - return; - - switch (op) { - case OLT: - case OGT: - case OGE: - case OLE: - DBG("FOLD neg commutative %d", np->op); - np->op = negop(op); - case OEQ: - case ONE: - case OADD: - case OMUL: - case OBAND: - case OBXOR: - case OBOR: - DBG("FOLD commutative %d", np->op); - np->left = r; - np->right = l; - break; - } -} - -static Node * -identity(Node *np) -{ - int iszeror, isoner; - int iszerol, isonel; - Node *lp = np->left, *rp = np->right; - - if (!rp) - return NULL; - - iszeror = cmpnode(rp, 0); - isoner = cmpnode(rp, 1), - iszerol = cmpnode(lp, 0); - isonel = cmpnode(lp, 1); - - switch (np->op) { - case OOR: - /* - * 1 || i => 1 (free right) - * i || 0 => i (free right) - * 0 || i => i (free left) - * i || 1 => i,1 (comma) - */ - if (isonel | iszeror) - goto free_right; - if (iszerol) - goto free_left; - if (isoner) - goto change_to_comma; - return NULL; - case OAND: - /* - * 0 && i => 0 (free right) - * i && 1 => i (free right) - * 1 && i => i (free left) - * i && 0 => i,0 (comma) - */ - if (iszerol | isoner) - goto free_right; - if (isonel) - goto free_left; - if (iszeror) - goto change_to_comma; - return NULL; - case OSHL: - case OSHR: - /* - * i >> 0 => i (free right) - * i << 0 => i (free right) - * 0 >> i => 0 (free right) - * 0 << i => 0 (free right) - */ - if (iszeror | iszerol) - goto free_right; - return NULL; - case OBXOR: - case OADD: - case OBOR: - case OSUB: - /* - * i + 0 => i - * i - 0 => i - * i | 0 => i - * i ^ 0 => i - */ - if (iszeror) - goto free_right; - return NULL; - case OMUL: - /* - * i * 0 => i,0 - * i * 1 => i - */ - if (iszeror) - goto change_to_comma; - if (isoner) - goto free_right; - return NULL; - case ODIV: - /* i / 1 => i */ - if (isoner) - goto free_right; - return NULL; - case OBAND: - /* i & ~0 => i */ - if (cmpnode(rp, -1)) - goto free_right; - return NULL; - case OMOD: - /* i % 1 => i,1 */ - /* TODO: i % 2^n => i & n-1 */ - if (isoner) - goto change_to_comma; - default: - return NULL; - } - -free_right: - DBG("FOLD identity %d", np->op); - np->left = NULL; - freetree(np); - return lp; - -free_left: - DBG("FOLD identity %d", np->op); - np->right = NULL; - freetree(np); - return rp; - -change_to_comma: - DBG("FOLD identity %d", np->op); - np->op = OCOMMA; - return np; -} - -static Node * -foldternary(Node *np, Node *cond, Node *body) -{ - if (!(cond->flags & NCONST)) - return np; - if (cmpnode(cond, 0)) { - np = body->right; - freetree(body->left); - } else { - np = body->left; - freetree(body->right); - } - - DBG("FOLD ternary"); - body->left = NULL; - body->right = NULL; - freetree(cond); - free(body); - return np; -} - -/* TODO: fold OCOMMA */ - -Node * -simplify(Node *np) -{ - Node *p, *l, *r; - - if (!np) - return NULL; - if (debug) - prtree(np); - - l = np->left = simplify(np->left); - r = np->right = simplify(np->right); - - switch (np->op) { - case OASK: - return foldternary(np, l, r); - case OCALL: - case OPAR: - case OSYM: - case OASSIGN: - case OA_MUL: - case OA_DIV: - case OA_MOD: - case OA_ADD: - case OA_SUB: - case OA_SHL: - case OA_SHR: - case OA_AND: - case OA_XOR: - case OA_OR: - return np; - case OSNEG: - case OCPL: - case OADDR: - case OPTR: - case INC: - case DEC: - case OCAST: - case ONEG: - assert(!r); - if ((p = foldunary(np, l)) != NULL) - return p; - return np; - default: - commutative(np, l, r); - if ((p = fold(np)) != NULL) - return p; - if ((p = identity(np)) != NULL) - return p; - return np; - } -} diff --git a/cc1/init.c b/cc1/init.c @@ -1,378 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/init.c"; -#include <stdint.h> -#include <stdlib.h> -#include <string.h> - -#include <cstd.h> -#include "../inc/scc.h" -#include "cc1.h" - - -typedef struct init Init; - -struct designator { - TINT pos; - Node *expr; - struct designator *next; -}; - -struct init { - TUINT pos; - TUINT max; - struct designator *tail; - struct designator *head; -}; - -static TINT -arydesig(Type *tp, Init *ip) -{ - TINT npos; - Node *np; - - if (tp->op != ARY) - errorp("array index in non-array initializer"); - next(); - np = constexpr(); - npos = np->sym->u.i; - if (npos < 0 || (tp->prop & TDEFINED) && npos >= tp->n.elem) { - errorp("array index in initializer exceeds array bounds"); - npos = 0; - } - freetree(np); - expect(']'); - return npos; -} - -static TINT -fielddesig(Type *tp, Init *ip) -{ - int ons; - Symbol *sym, **p; - - if (!(tp->prop & TAGGREG)) - errorp("field name not in record or union initializer"); - ons = namespace; - namespace = tp->ns; - next(); - namespace = ons; - if (yytoken != IDEN) - unexpected(); - sym = yylval.sym; - next(); - if ((sym->flags & SDECLARED) == 0) { - errorp("unknown field '%s' specified in initializer", - sym->name); - return 0; - } - for (p = tp->p.fields; *p != sym; ++p) - ; - return p - tp->p.fields; -} - -static Init * -init(Init *ip) -{ - ip->tail = ip->head = NULL; - ip->pos = ip->max = 0; - return ip; -} - -static Node * -str2ary(Type *tp) -{ - Node *np; - Type *btp = tp->type;; - Symbol *sym; - size_t len; - char *s; - - np = assign(); - sym = np->left->sym; - if (btp != chartype && btp != uchartype && btp != schartype) { - errorp("array of inappropriate type initialized from string constant"); - return constnode(zero); - } - - len = sym->type->n.elem-1; - if (!(tp->prop & TDEFINED)) { - tp->n.elem = len+1; - deftype(tp); - } else if (tp->n.elem < len) { - warn("initializer-string for array of chars is too long"); - } - - len = tp->n.elem; - s = sym->u.s; - sym = newstring(NULL, len); - strncpy(sym->u.s, s, len); - np->sym = sym; - np->type = sym->type; - - return np; -} - -static Node * -initialize(Type *tp) -{ - Node *np; - Symbol *sym; - - if (tp->op == ARY && yytoken == STRING) - return str2ary(tp); - - if (yytoken == '{' || tp->op == STRUCT || tp->op == ARY) - return initlist(tp); - - np = assign(); - if (eqtype(tp, np->type, 1)) - return np; - - np = convert(decay(np), tp, 0); - if (!np) { - errorp("incorrect initializer"); - return constnode(zero); - } - - return simplify(np); -} - -static Node * -mkcompound(Init *ip, Type *tp) -{ - Node **v, **p; - size_t n; - struct designator *dp, *next; - Symbol *sym; - - if (tp->op == UNION) { - Node *np = NULL; - - v = xmalloc(sizeof(*v)); - for (dp = ip->head; dp; dp = next) { - freetree(np); - np = dp->expr; - next = dp->next; - free(dp); - } - *v = np; - } else { - n = (tp->prop&TDEFINED) ? tp->n.elem : ip->max; - if (n == 0) { - v = NULL; - } else if (n > SIZE_MAX / sizeof(*v)) { - errorp("compound literal too big"); - return constnode(zero); - } else { - n *= sizeof(*v); - v = memset(xmalloc(n), 0, n); - - for (dp = ip->head; dp; dp = next) { - p = &v[dp->pos]; - freetree(*p); - *p = dp->expr; - next = dp->next; - free(dp); - } - } - } - - sym = newsym(NS_IDEN, NULL); - sym->u.init = v; - sym->type = tp; - sym->flags |= SINITLST; - - return constnode(sym); -} - -static void -newdesig(Init *ip, Node *np) -{ - struct designator *dp; - - dp = xmalloc(sizeof(*dp)); - dp->pos = ip->pos; - dp->expr = np; - dp->next = NULL; - - if (ip->head == NULL) { - ip->head = ip->tail = dp; - } else { - ip->tail->next = dp; - ip->tail = dp; - } - - if (ip->pos+1 > ip->max) - ip->max = ip->pos+1; -} - -Node * -initlist(Type *tp) -{ - Init in; - Node *np; - Type *curtp; - int braces, scalar, toomany, outbound; - TINT nelem = tp->n.elem; - static int depth; - - if (depth == NR_SUBTYPE) - error("too many nested initializers"); - ++depth; - init(&in); - braces = scalar = toomany = 0; - - if (accept('{')) - braces = 1; - - do { - curtp = inttype; - switch (yytoken) { - case '[': - in.pos = arydesig(tp, &in); - curtp = tp->type; - goto desig_list; - case '.': - in.pos = fielddesig(tp, &in); - if (in.pos < nelem) - curtp = tp->p.fields[in.pos]->type; - desig_list: - if (yytoken == '[' || yytoken == '.') { - np = initlist(curtp); - goto new_desig; - } - expect('='); - default: - outbound = 0; - - switch (tp->op) { - case ARY: - curtp = tp->type; - if (!(tp->prop & TDEFINED) || in.pos < tp->n.elem) - break; - if (!toomany) - warn("excess elements in array initializer"); - toomany = 1; - outbound = 1; - break; - case UNION: - case STRUCT: - if (in.pos < nelem) { - curtp = tp->p.fields[in.pos]->type; - break; - } - if (!toomany) - warn("excess elements in struct initializer"); - toomany = 1; - outbound = 1; - break; - default: - curtp = tp; - if (!scalar) - warn("braces around scalar initializer"); - scalar = 1; - if (in.pos == 0) - break; - if (!toomany) - warn("excess elements in scalar initializer"); - toomany = 1; - outbound = 1; - break; - } - np = initialize(curtp); - if (outbound) { - freetree(np); - np = NULL; - } - } - -new_desig: - if (np) - newdesig(&in, np); - if (++in.pos == 0) - errorp("compound literal too big"); - if (nelem == in.pos && !braces) - break; - } while (accept(',')); - - if (braces) - expect('}'); - - - if (tp->op == ARY && !(tp->prop & TDEFINED)) { - tp->n.elem = in.max; - deftype(tp); - } - if (in.max == 0) { - errorp("empty braced initializer"); - return constnode(zero); - } - - return mkcompound(&in, tp); -} - -static void -autoinit(Symbol *sym, Node *np) -{ - Symbol *hidden; - Type *tp = sym->type; - size_t n; /* FIXME: It should be SIZET */ - -repeat: - switch (tp->op) { - case UNION: - np = np->sym->u.init[0]; - tp = np->type; - goto repeat; - case ARY: - case STRUCT: - if (!(np->flags & NCONST)) - abort(); /* TODO */ - hidden = newsym(NS_IDEN, NULL); - hidden->type = sym->type; - hidden->flags |= SLOCAL | SHASINIT; - emit(ODECL, hidden); - emit(OINIT, np); - emit(ODECL, sym); - emit(OEXPR, - node(OASSIGN, tp, varnode(sym), varnode(hidden))); - break; - default: - emit(ODECL, sym); - np = node(OASSIGN, tp, varnode(sym), np); - emit(OEXPR, np); - break; - } -} - -void -initializer(Symbol *sym, Type *tp) -{ - Node *np; - int flags = sym->flags; - - if (tp->op == FTN) { - errorp("function '%s' initialized like a variable", - sym->name); - tp = inttype; - } - np = initialize(tp); - - if (flags & SDEFINED) { - errorp("redeclaration of '%s'", sym->name); - } else if ((flags & (SGLOBAL|SLOCAL|SPRIVATE)) != 0) { - if (!(np->flags & NCONST)) { - errorp("initializer element is not constant"); - return; - } - sym->flags |= SHASINIT; - sym->flags &= ~SEMITTED; - emit(ODECL, sym); - emit(OINIT, np); - sym->flags |= SDEFINED; - } else if ((flags & (SEXTERN|STYPEDEF)) != 0) { - errorp("'%s' has both '%s' and initializer", - sym->name, (flags&SEXTERN) ? "extern" : "typedef"); - } else { - autoinit(sym, np); - } -} diff --git a/cc1/lex.c b/cc1/lex.c @@ -1,801 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/lex.c"; -#include <assert.h> -#include <ctype.h> -#include <errno.h> -#include <limits.h> -#include <setjmp.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <cstd.h> -#include "../inc/scc.h" -#include "cc1.h" - -int yytoken; -struct yystype yylval; -char yytext[STRINGSIZ+3]; -unsigned short yylen; -int lexmode = CCMODE; -unsigned lineno; -char filenam[FILENAME_MAX]; - -int namespace = NS_IDEN; -static int safe; -Input *input; - -void -ilex(void) -{ - static struct keyword keys[] = { - {"auto", SCLASS, AUTO}, - {"break", BREAK, BREAK}, - {"_Bool", TYPE, BOOL}, - {"__builtin_va_list", TYPE, VA_LIST}, - {"case", CASE, CASE}, - {"char", TYPE, CHAR}, - {"const", TQUALIFIER, CONST}, - {"continue", CONTINUE, CONTINUE}, - {"default", DEFAULT, DEFAULT}, - {"do", DO, DO}, - {"double", TYPE, DOUBLE}, - {"else", ELSE, ELSE}, - {"enum", TYPE, ENUM}, - {"extern", SCLASS, EXTERN}, - {"float", TYPE, FLOAT}, - {"for", FOR, FOR}, - {"goto", GOTO, GOTO}, - {"if", IF, IF}, - {"inline", TQUALIFIER, INLINE}, - {"int", TYPE, INT}, - {"long", TYPE, LONG}, - {"register", SCLASS, REGISTER}, - {"restrict", TQUALIFIER, RESTRICT}, - {"return", RETURN, RETURN}, - {"short", TYPE, SHORT}, - {"signed", TYPE, SIGNED}, - {"sizeof", SIZEOF, SIZEOF}, - {"static", SCLASS, STATIC}, - {"struct", TYPE, STRUCT}, - {"switch", SWITCH, SWITCH}, - {"typedef", SCLASS, TYPEDEF}, - {"union", TYPE, UNION}, - {"unsigned", TYPE, UNSIGNED}, - {"void", TYPE, VOID}, - {"volatile", TQUALIFIER, VOLATILE}, - {"while", WHILE, WHILE}, - {NULL, 0, 0}, - }; - keywords(keys, NS_KEYWORD); -} - -void -setloc(char *fname, unsigned line) -{ - size_t len; - - if ((len = strlen(fname)) >= FILENAME_MAX) - die("cc1: %s: file name too long", fname); - memmove(filenam, fname, len); - filenam[len] = '\0'; - - free(input->filenam); - input->filenam = xstrdup(fname); - lineno = input->lineno = line; -} - -void -addinput(char *fname, Symbol *hide, char *buffer) -{ - FILE *fp; - char *extp; - unsigned flags; - int infileln; - Input *newip, *curip = input; - - if (hide) { - /* this is a macro expansion */ - fp = NULL; - if (hide->hide == UCHAR_MAX) - die("cc1: too many macro expansions"); - ++hide->hide; - flags = IMACRO; - } else if (fname) { - /* a new file */ - if ((fp = fopen(fname, "r")) == NULL) - die("cc1: %s: %s", fname, strerror(errno)); - flags = IFILE; - if (curip && onlyheader) { - infileln = strlen(infile); - if (extp = strrchr(infile, '.')) - infileln -= strlen(extp); - printf("%.*s.o: %s %s\n", - infileln, infile, infile, fname); - } - } else { - /* reading from stdin */ - fp = stdin; - fname = "<stdin>"; - flags = ISTDIN; - } - - newip = xmalloc(sizeof(*newip)); - - if (!buffer) { - buffer = xmalloc(INPUTSIZ); - buffer[0] = '\0'; - } - - if (curip) - curip->lineno = lineno; - - newip->p = newip->begin = newip->line = buffer; - newip->filenam = NULL; - newip->lineno = 0; - newip->next = curip; - newip->fp = fp; - newip->hide = hide; - newip->flags = flags; - input = newip; - - setloc(fname, (curip) ? curip->lineno : newip->lineno); -} - -void -delinput(void) -{ - Input *ip = input; - Symbol *hide = ip->hide; - - switch (ip->flags & ITYPE) { - case IFILE: - if (fclose(ip->fp)) - die("cc1: %s: %s", ip->filenam, strerror(errno)); - break; - case IMACRO: - assert(hide->hide == 1); - --hide->hide; - break; - } - input = ip->next; - free(ip->filenam); - free(ip->line); - if (input) { - lineno = input->lineno; - strcpy(filenam, input->filenam); - } -} - -static void -newline(void) -{ - if (++lineno == 0) - die("cc1: %s: file too long", filenam); -} - -/* - * Read the next character from the input file, counting number of lines - * and joining lines escaped with \ - */ -static int -readchar(void) -{ - FILE *fp = input->fp; - int c; - -repeat: - switch (c = getc(fp)) { - case '\\': - if ((c = getc(fp)) == '\n') { - newline(); - goto repeat; - } - ungetc(c, fp); - c = '\\'; - break; - case '\n': - newline(); - break; - default: - if (!isprint(c) && !ispunct(c) && !isspace(c)) - warn("invalid input character. The shame of UB is yours"); - break; - } - - return c; -} - -/* - * discard a C comment. This function is only called from readline - * because it is impossible to have a comment in a macro, because - * comments are always discarded before processing any cpp directive - */ -static void -comment(int type) -{ - int c; - -repeat: - while ((c = readchar()) != EOF && c != type) - ; - - if (c == EOF) { - errorp("unterminated comment"); - return; - } - - if (type == '*' && (c = readchar()) != '/') - goto repeat; -} - -/* - * readline is used to read a full logic line from a file. - * It discards comments and check that the line fits in - * the input buffer - */ -static int -readline(void) -{ - char *bp, *lim; - int c, peekc = 0; - - if (feof(input->fp)) { - input->flags |= IEOF; - return 0; - } - - *input->line = '\0'; - lim = &input->line[INPUTSIZ-1]; - for (bp = input->line; bp < lim-1; *bp++ = c) { - c = (peekc) ? peekc : readchar(); - peekc = 0; - if (c == '\n' || c == EOF) - break; - if (c != '/') - continue; - - /* check for /* or // */ - peekc = readchar(); - if (peekc != '*' && peekc != '/') - continue; - comment((peekc == '/') ? '\n' : '*'); - peekc = 0; - c = ' '; - } - - input->begin = input->p = input->line; - if (bp == lim-1) { - errorp("line too long"); - --bp; - } - *bp++ = '\n'; - *bp = '\0'; - - return 1; -} - -/* - * moreinput gets more bytes to be passed to the lexer. - * It can take more bytes from macro expansions or - * directly reading from files. When a cpp directive - * is processed the line is discarded because it must not - * be passed to the lexer - */ -static int -moreinput(void) -{ - int wasexpand = 0; - -repeat: - if (!input) - return 0; - - if (*input->p == '\0') { - if ((input->flags&ITYPE) == IMACRO) { - wasexpand = 1; - input->flags |= IEOF; - } - if (input->flags & IEOF) { - delinput(); - goto repeat; - } - if (!readline() || cpp()) { - *input->p = '\0'; - goto repeat; - } - } - - if (onlycpp && !wasexpand) - ppragmaln(); - return 1; -} - -static void -tok2str(void) -{ - if ((yylen = input->p - input->begin) > INTIDENTSIZ) - error("token too big"); - memcpy(yytext, input->begin, yylen); - yytext[yylen] = '\0'; - input->begin = input->p; -} - -static Symbol * -readint(char *s, int base, int sign, Symbol *sym) -{ - Type *tp = sym->type; - struct limits *lim; - TUINT u, val, max; - int c; - - lim = getlimits(tp); - max = lim->max.i; - if (*s == '0') - ++s; - if (toupper(*s) == 'X') - ++s; - - for (u = 0; isxdigit(c = *s++); u = u*base + val) { - static char letters[] = "0123456789ABCDEF"; - val = strchr(letters, toupper(c)) - letters; - repeat: - if (u <= max/base && u*base <= max - val) - continue; - if (tp->prop & TSIGNED) { - if (tp == inttype) - tp = (base==10) ? longtype : uinttype; - else if (tp == longtype) - tp = (base==10) ? llongtype : ulongtype; - else - goto overflow; - } else { - if (tp == uinttype) - tp = (sign==UNSIGNED) ? ulongtype : longtype; - else if (tp == ulongtype) - tp = (sign==UNSIGNED) ? ullongtype : llongtype; - else - goto overflow; - } - sym->type = tp; - lim = getlimits(tp); - max = lim->max.i; - goto repeat; - } - - if (tp->prop & TSIGNED) - sym->u.i = u; - else - sym->u.u = u; - - return sym; - -overflow: - errorp("overflow in integer constant"); - return sym; -} - -static int -integer(char *s, int base) -{ - Type *tp; - Symbol *sym; - unsigned size, sign; - - for (size = sign = 0; ; ++input->p) { - switch (toupper(*input->p)) { - case 'L': - if (size == LLONG) - goto wrong_type; - size = (size == LONG) ? LLONG : LONG; - continue; - case 'U': - if (sign == UNSIGNED) - goto wrong_type; - sign = UNSIGNED; - continue; - default: - goto convert; - wrong_type: - error("invalid suffix in integer constant"); - } - } - -convert: - tp = ctype(INT, sign, size); - sym = newsym(NS_IDEN, NULL); - sym->type = tp; - sym->flags |= SCONSTANT; - yylval.sym = readint(s, base, sign, sym); - return CONSTANT; -} - -static char * -digits(int base) -{ - char *p; - int c; - - for (p = input->p; c = *p; ++p) { - switch (base) { - case 8: - if (!strchr("01234567", c)) - goto end; - break; - case 10: - if (!isdigit(c)) - goto end; - break; - case 16: - if (!isxdigit(c)) - goto end; - break; - } - } -end: - input->p = p; - tok2str(); - return yytext; -} - -static int -number(void) -{ - int base; - - if (*input->p != '0') { - base = 10; - } else { - if (toupper(*++input->p) == 'X') { - ++input->p; - base = 16; - } else { - base = 8; - } - } - - return integer(digits(base), base); -} - -static int -escape(void) -{ - int c, base; - - switch (*++input->p) { - case 'a': return '\a'; - case 'f': return '\f'; - case 'n': return '\n'; - case 'r': return '\r'; - case 't': return '\t'; - case 'v': return '\v'; - case '"': return '"'; - case '\'': return '\''; - case '\\': return '\\'; - case '\?': return '\?'; - case 'u': - /* - * FIXME: universal constants are not correctly handled - */ - if (!isdigit(*++input->p)) - warn("incorrect digit for numerical character constant"); - base = 10; - break; - case 'x': - if (!isxdigit(*++input->p)) - warn("\\x used with no following hex digits"); - base = 16; - break; - case '0': - if (!strchr("01234567", *++input->p)) - warn("\\0 used with no following octal digits"); - base = 8; - break; - default: - warn("unknown escape sequence"); - return ' '; - } - errno = 0; - c = strtoul(input->p, &input->p, base); - if (errno || c > 255) - warn("character constant out of range"); - --input->p; - return c; -} - -static int -character(void) -{ - int c; - Symbol *sym; - - if ((c = *++input->p) == '\\') - c = escape(); - else - c = *input->p; - ++input->p; - if (*input->p != '\'') - errorp("invalid character constant"); - else - ++input->p; - - sym = newsym(NS_IDEN, NULL); - sym->u.i = c; - sym->type = inttype; - yylval.sym = sym; - tok2str(); - return CONSTANT; -} - -static int -string(void) -{ - char *bp = yytext; - int c; - - *bp++ = '"'; - for (++input->p; (c = *input->p) != '"'; ++input->p) { - if (c == '\0') { - errorp("missing terminating '\"' character"); - break; - } - if (c == '\\') - c = escape(); - if (bp == &yytext[STRINGSIZ+1]) { - /* TODO: proper error handling here */ - error("string too long"); - } - *bp++ = c; - } - - input->begin = ++input->p; - *bp = '\0'; - - yylen = bp - yytext + 1; - yylval.sym = newstring(yytext+1, yylen-1); - *bp++ = '"'; - *bp = '\0'; - return STRING; -} - -static int -iden(void) -{ - Symbol *sym; - char *p, *begin; - - begin = input->p; - for (p = begin; isalnum(*p) || *p == '_'; ++p) - ; - input->p = p; - tok2str(); - if ((sym = lookup(NS_CPP, yytext, NOALLOC)) != NULL) { - if (!disexpand && !sym->hide && expand(begin, sym)) - return next(); - } - sym = lookup(namespace, yytext, ALLOC); - yylval.sym = sym; - if (sym->flags & SCONSTANT) - return CONSTANT; - if (sym->token != IDEN) - yylval.token = sym->u.token; - return sym->token; -} - -static int -follow(int expect, int ifyes, int ifno) -{ - if (*input->p++ == expect) - return ifyes; - --input->p; - return ifno; -} - -static int -minus(void) -{ - switch (*input->p++) { - case '-': return DEC; - case '>': return INDIR; - case '=': return SUB_EQ; - default: --input->p; return '-'; - } -} - -static int -plus(void) -{ - switch (*input->p++) { - case '+': return INC; - case '=': return ADD_EQ; - default: --input->p; return '+'; - } -} - -static int -relational(int op, int equal, int shift, int assig) -{ - int c; - - if ((c = *input->p++) == '=') - return equal; - if (c == op) - return follow('=', assig, shift); - --input->p; - return op; -} - -static int -logic(int op, int equal, int logic) -{ - int c; - - if ((c = *input->p++) == '=') - return equal; - if (c == op) - return logic; - --input->p; - return op; -} - -static int -dot(void) -{ - int c; - - if ((c = *input->p) != '.') - return '.'; - if ((c = *++input->p) != '.') - error("incorrect token '..'"); - ++input->p; - return ELLIPSIS; -} - -static int -operator(void) -{ - int t; - - switch (t = *input->p++) { - case '<': t = relational('<', LE, SHL, SHL_EQ); break; - case '>': t = relational('>', GE, SHR, SHR_EQ); break; - case '&': t = logic('&', AND_EQ, AND); break; - case '|': t = logic('|', OR_EQ, OR); break; - case '=': t = follow('=', EQ, '='); break; - case '^': t = follow('=', XOR_EQ, '^'); break; - case '*': t = follow('=', MUL_EQ, '*'); break; - case '/': t = follow('=', DIV_EQ, '/'); break; - case '!': t = follow('=', NE, '!'); break; - case '#': t = follow('#', '$', '#'); break; - case '-': t = minus(); break; - case '+': t = plus(); break; - case '.': t = dot(); break; - } - tok2str(); - return t; -} - -/* TODO: Ensure that namespace is NS_IDEN after a recovery */ - -/* - * skip all the spaces until the next token. When we are in - * CPPMODE \n is not considered a whitespace - */ -static int -skipspaces(void) -{ - int c; - - for (;;) { - switch (c = *input->p) { - case '\n': - if (lexmode == CPPMODE) - goto return_byte; - ++input->p; - case '\0': - if (!moreinput()) - return EOF; - break; - case ' ': - case '\t': - case '\v': - case '\r': - case '\f': - ++input->p; - break; - default: - goto return_byte; - } - } - -return_byte: - input->begin = input->p; - return c; -} - -int -next(void) -{ - int c; - - if ((c = skipspaces()) == EOF) - yytoken = EOFTOK; - else if (isalpha(c) || c == '_') - yytoken = iden(); - else if (isdigit(c)) - yytoken = number(); - else if (c == '"') - yytoken = string(); - else if (c == '\'') - yytoken = character(); - else - yytoken = operator(); - - if (yytoken == EOF) { - strcpy(yytext, "<EOF>"); - if (cppctx) - errorp("#endif expected"); - } - - DBG("TOKEN %s", yytext); - return yytoken; -} - -void -expect(int tok) -{ - if (yytoken != tok) { - if (isgraph(tok)) - errorp("expected '%c' before '%s'", tok, yytext); - else - errorp("unexpected '%s'", yytext); - } else { - next(); - } -} - -int -ahead(void) -{ - skipspaces(); - return *input->begin; -} - -void -setsafe(int type) -{ - safe = type; -} - -void -discard(void) -{ - extern jmp_buf recover; - int c; - - input->begin = input->p; - for (c = yytoken; ; c = *input->begin++) { - switch (safe) { - case END_COMP: - if (c == '}') - goto jump; - goto semicolon; - case END_COND: - if (c == ')') - goto jump; - break; - case END_LDECL: - if (c == ',') - goto jump; - case END_DECL: - semicolon: - if (c == ';') - goto jump; - break; - } - if (c == '\0' && !moreinput()) - exit(1); - } -jump: - yytoken = c; - longjmp(recover, 1); -} diff --git a/cc1/main.c b/cc1/main.c @@ -1,102 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/main.c"; -#include <setjmp.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include "../inc/arg.h" -#include "../inc/scc.h" -#include "cc1.h" - -char *argv0, *infile; - -int warnings; -jmp_buf recover; - -static struct items uflags; -int onlycpp, onlyheader; - - -extern int failure; - -static void -defmacro(char *macro) -{ - char *p = strchr(macro, '='); - - if (p) - *p++ = '\0'; - else - p = "1"; - - defdefine(macro, p, "command-line"); -} - -static void -usage(void) -{ - fputs("usage: cc1 [-Ewd] [-D def[=val]]... [-U def]... " - "[-I dir]... [-o output] [input]\n", stderr); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - int i; - - ilex(); - icpp(); - icode(); - ibuilts(); - - ARGBEGIN { - case 'D': - defmacro(EARGF(usage())); - break; - case 'M': - onlyheader = 1; - break; - case 'E': - onlycpp = 1; - break; - case 'I': - incdir(EARGF(usage())); - break; - case 'U': - newitem(&uflags, EARGF(usage())); - break; - case 'd': - DBGON(); - break; - case 'w': - warnings = 1; - break; - default: - usage(); - } ARGEND - - if (argc > 1) - usage(); - - for (i = 0; i < uflags.n; ++i) - undefmacro(uflags.s[i]); - - infile = (*argv) ? *argv : "<stdin>"; - addinput(*argv, NULL, NULL); - - /* - * we cannot initialize arch until we have an - * output stream, because we maybe want to emit new types - */ - iarch(); - if (onlycpp || onlyheader) { - outcpp(); - } else { - for (next(); yytoken != EOFTOK; decl()) - ; - } - - return failure; -} diff --git a/cc1/stmt.c b/cc1/stmt.c @@ -1,386 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/stmt.c"; -#include <stddef.h> -#include <setjmp.h> - -#include <cstd.h> -#include "../inc/scc.h" -#include "cc1.h" - -#define NEGATE 1 -#define NONEGATE 0 - -Symbol *curfun; - -static void stmt(Symbol *lbreak, Symbol *lcont, Switch *lswitch); - -static void -label(void) -{ - Symbol *sym; - - switch (yytoken) { - case IDEN: - case TYPEIDEN: - sym = lookup(NS_LABEL, yytext, ALLOC); - if (sym->flags & SDEFINED) - error("label '%s' already defined", yytext); - if ((sym->flags & SDECLARED) == 0) - sym = install(NS_LABEL, sym); - sym->flags |= SDEFINED; - emit(OLABEL, sym); - next(); - expect(':'); - break; - default: - unexpected(); - } -} - -static void -stmtexp(Symbol *lbreak, Symbol *lcont, Switch *lswitch) -{ - Node *np; - - if (accept(';')) - return; - if (yytoken == IDEN && ahead() == ':') { - label(); - stmt(lbreak, lcont, lswitch); - return; - } - np = expr(); - if ((np->flags & NEFFECT) == 0) - warn("expression without side effects"); - emit(OEXPR, np); - expect(';'); -} - -static Node * -condition(int neg) -{ - Node *np; - - expect('('); - np = condexpr(neg); - expect(')'); - - return np; -} - -static void -While(Symbol *lbreak, Symbol *lcont, Switch *lswitch) -{ - Symbol *begin; - Node *np; - - begin = newlabel(); - lcont = newlabel(); - lbreak = newlabel(); - - expect(WHILE); - np = condition(NONEGATE); - - emit(OJUMP, lcont); - - emit(OBLOOP, NULL); - emit(OLABEL, begin); - stmt(lbreak, lcont, lswitch); - emit(OLABEL, lcont); - emit(OBRANCH, begin); - emit(OEXPR, np); - emit(OELOOP, NULL); - - emit(OLABEL, lbreak); -} - -static void -For(Symbol *lbreak, Symbol *lcont, Switch *lswitch) -{ - Symbol *begin, *cond; - Node *econd, *einc; - - begin = newlabel(); - lcont = newlabel(); - cond = newlabel(); - lbreak = newlabel(); - - pushctx(); - - expect(FOR); - expect('('); - switch (yytoken) { - case TYPE: - case TYPEIDEN: - case TQUALIFIER: - case SCLASS: - decl(); - break; - default: - emit(OEXPR, expr()); - case ';': - expect(';'); - break; - } - econd = (yytoken != ';') ? condexpr(NONEGATE) : NULL; - expect(';'); - einc = (yytoken != ')') ? expr() : NULL; - expect(')'); - - emit(OJUMP, cond); - - emit(OBLOOP, NULL); - emit(OLABEL, begin); - stmt(lbreak, lcont, lswitch); - emit(OLABEL, lcont); - emit(OEXPR, einc); - emit(OLABEL, cond); - emit((econd) ? OBRANCH : OJUMP, begin); - emit(OEXPR, econd); - emit(OELOOP, NULL); - - emit(OLABEL, lbreak); - - popctx(); -} - -static void -Dowhile(Symbol *lbreak, Symbol *lcont, Switch *lswitch) -{ - Symbol *begin; - Node *np; - - begin = newlabel(); - lcont = newlabel(); - lbreak = newlabel(); - - expect(DO); - - emit(OBLOOP, NULL); - emit(OLABEL, begin); - stmt(lbreak, lcont, lswitch); - expect(WHILE); - np = condition(NONEGATE); - emit(OLABEL, lcont); - emit(OBRANCH, begin); - emit(OEXPR, np); - emit(OELOOP, NULL); - - emit(OLABEL, lbreak); -} - -static void -Return(Symbol *lbreak, Symbol *lcont, Switch *lswitch) -{ - Node *np; - Type *tp = curfun->type->type; - - expect(RETURN); - np = (yytoken != ';') ? decay(expr()) : NULL; - expect(';'); - if (!np) { - if (tp != voidtype) - warn("function returning non void returns no value"); - tp = voidtype; - } else if (np->type != tp) { - if (tp == voidtype) - warn("function returning void returns a value"); - else if ((np = convert(np, tp, 0)) == NULL) - errorp("incorrect type in return"); - } - emit(ORET, NULL); - emit(OEXPR, np); -} - -static void -Break(Symbol *lbreak, Symbol *lcont, Switch *lswitch) -{ - expect(BREAK); - if (!lbreak) { - errorp("break statement not within loop or switch"); - } else { - emit(OJUMP, lbreak); - expect(';'); - } -} - -static void -Continue(Symbol *lbreak, Symbol *lcont, Switch *lswitch) -{ - expect(CONTINUE); - if (!lcont) { - errorp("continue statement not within loop"); - } else { - emit(OJUMP, lcont); - expect(';'); - } -} - -static void -Goto(Symbol *lbreak, Symbol *lcont, Switch *lswitch) -{ - Symbol *sym; - - namespace = NS_LABEL; - next(); - namespace = NS_IDEN; - - if (yytoken != IDEN) - unexpected(); - sym = yylval.sym; - if ((sym->flags & SDECLARED) == 0) - sym = install(NS_LABEL, sym); - sym->flags |= SUSED; - emit(OJUMP, sym); - next(); - expect(';'); -} - -static void -Swtch(Symbol *obr, Symbol *lcont, Switch *osw) -{ - Switch sw = {0}; - Node *cond; - Symbol *lbreak; - - expect(SWITCH); - - expect ('('); - if ((cond = convert(expr(), inttype, 0)) == NULL) { - errorp("incorrect type in switch statement"); - cond = constnode(zero); - } - expect (')'); - - lbreak = newlabel(); - emit(OBSWITCH, NULL); - emit(OEXPR, cond); - stmt(lbreak, lcont, &sw); - emit(OESWITCH, lbreak); - emit(OLABEL, lbreak); -} - -static void -Case(Symbol *lbreak, Symbol *lcont, Switch *sw) -{ - Node *np; - Symbol *label; - - expect(CASE); - if ((np = constexpr()) == NULL) - errorp("case label does not reduce to an integer constant"); - if (!sw) { - errorp("case label not within a switch statement"); - } else if (sw->nr >= 0 && ++sw->nr == NR_SWITCH) { - errorp("too many case labels for a switch statement"); - sw->nr = -1; - } - expect(':'); - - label = newlabel(); - emit(OCASE, label); - emit(OEXPR, np); - emit(OLABEL, label); - stmt(lbreak, lcont, sw); -} - -static void -Default(Symbol *lbreak, Symbol *lcont, Switch *sw) -{ - Symbol *label = newlabel(); - - if (sw->hasdef) - errorp("multiple default labels in one switch"); - sw->hasdef = 1; - expect(DEFAULT); - expect(':'); - emit(ODEFAULT, label); - emit(OLABEL, label); - stmt(lbreak, lcont, sw); -} - -static void -If(Symbol *lbreak, Symbol *lcont, Switch *lswitch) -{ - Symbol *end, *lelse; - Node *np; - - lelse = newlabel(); - expect(IF); - np = condition(NEGATE); - emit(OBRANCH, lelse); - emit(OEXPR, np); - stmt(lbreak, lcont, lswitch); - if (accept(ELSE)) { - end = newlabel(); - emit(OJUMP, end); - emit(OLABEL, lelse); - stmt(lbreak, lcont, lswitch); - emit(OLABEL, end); - } else { - emit(OLABEL, lelse); - } -} - -static void -blockit(Symbol *lbreak, Symbol *lcont, Switch *lswitch) -{ - switch (yytoken) { - case TYPEIDEN: - if (ahead() == ':') - goto parse_stmt; - case TYPE: - case TQUALIFIER: - case SCLASS: - decl(); - return; - default: - parse_stmt: - stmt(lbreak, lcont, lswitch); - } -} - -void -compound(Symbol *lbreak, Symbol *lcont, Switch *lswitch) -{ - static int nested; - - pushctx(); - expect('{'); - - if (nested == NR_BLOCK) - error("too many nesting levels of compound statements"); - - ++nested; - for (;;) { - if (yytoken == '}') - break; - blockit(lbreak, lcont, lswitch); - } - --nested; - - popctx(); - expect('}'); -} - -static void -stmt(Symbol *lbreak, Symbol *lcont, Switch *lswitch) -{ - void (*fun)(Symbol *, Symbol *, Switch *); - - switch (yytoken) { - case '{': fun = compound; break; - case RETURN: fun = Return; break; - case WHILE: fun = While; break; - case FOR: fun = For; break; - case DO: fun = Dowhile; break; - case IF: fun = If; break; - case BREAK: fun = Break; break; - case CONTINUE: fun = Continue; break; - case GOTO: fun = Goto; break; - case SWITCH: fun = Swtch; break; - case CASE: fun = Case; break; - case DEFAULT: fun = Default; break; - default: fun = stmtexp; break; - } - (*fun)(lbreak, lcont, lswitch); -} diff --git a/cc1/symbol.c b/cc1/symbol.c @@ -1,353 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/symbol.c"; -#include <assert.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <cstd.h> -#include "../inc/scc.h" -#include "cc1.h" - -#define NR_SYM_HASH 64 -#define NR_CPP_HASH 32 -#define NR_LBL_HASH 16 - -unsigned curctx; -static unsigned short counterid; - -static Symbol *head, *labels; -static Symbol *htab[NR_SYM_HASH]; -static Symbol *htabcpp[NR_CPP_HASH]; -static Symbol *htablbl[NR_LBL_HASH]; - -#ifndef NDEBUG -void -dumpstab(Symbol **tbl, char *msg) -{ - Symbol **bp, *sym; - unsigned size; - - fprintf(stderr, "Symbol Table dump at ctx=%u\n%s\n", curctx, msg); - if (tbl == htab) - size = NR_SYM_HASH; - else if (tbl == htabcpp) - size = NR_CPP_HASH; - else if (tbl == htablbl) - size = NR_LBL_HASH; - else - abort(); - - for (bp = tbl; bp < &tbl[size]; ++bp) { - if (*bp == NULL) - continue; - fprintf(stderr, "%d", (int) (bp - htab)); - for (sym = *bp; sym; sym = sym->hash) - fprintf(stderr, "->[%d,%d:'%s'=%p]", - sym->ns, sym->ctx, sym->name, (void *) sym); - putc('\n', stderr); - } - fputs("head:", stderr); - for (sym = head; sym; sym = sym->next) { - fprintf(stderr, "->[%d,%d:'%s'=%p]", - sym->ns, sym->ctx, - (sym->name) ? sym->name : "", (void *) sym); - } - fputs("\nlabels:", stderr); - for (sym = labels; sym; sym = sym->next) { - fprintf(stderr, "->[%d,%d:'%s'=%p]", - sym->ns, sym->ctx, - (sym->name) ? sym->name : "", (void *) sym); - } - putc('\n', stderr); -} -#endif - -static Symbol ** -hash(char *s, int ns) -{ - unsigned c, h, size; - Symbol **tab; - - for (h = 0; c = *s; ++s) - h = h*33 ^ c; - - switch (ns) { - case NS_CPP: - tab = htabcpp; - size = NR_CPP_HASH-1; - break; - case NS_LABEL: - tab = htablbl; - size = NR_LBL_HASH-1; - break; - default: - tab = htab; - size = NR_SYM_HASH-1; - break; - } - return &tab[h & size]; -} - -static void -unlinkhash(Symbol *sym) -{ - Symbol **h; - - if ((sym->flags & SDECLARED) == 0) - return; - h = hash(sym->name, sym->ns); - assert(sym->ns == NS_CPP || *h == sym); - while (*h != sym) - h = &(*h)->hash; - *h = sym->hash; -} - -void -pushctx(void) -{ - DBG("SYM: pushed context %d", curctx+1); - if (++curctx == NR_BLOCK+1) - error("too many nested blocks"); -} - -void -killsym(Symbol *sym) -{ - short f; - char *name; - - if (!sym) - return; - f = sym->flags; - if (f & SSTRING) - free(sym->u.s); - if (sym->ns == NS_TAG) - sym->type->prop &= ~TDEFINED; - unlinkhash(sym); - if ((name = sym->name) != NULL) { - switch (sym->ns) { - case NS_LABEL: - if ((f & SDEFINED) == 0) - errorp("label '%s' is not defined", name); - case NS_IDEN: - if ((f & (SUSED|SGLOBAL|SDECLARED)) == SDECLARED) - warn("'%s' defined but not used", name); - break; - } - } - free(name); - free(sym); -} - -void -popctx(void) -{ - Symbol *next, *sym; - int ns, dangling = 0; - - DBG("SYM: poped context %d", curctx); - /* - * we have to be careful before popping the current - * context, because since the parser is one token - * ahead it may already have read an identifier at - * this point, and yylval.sym is a pointer to - * the symbol associated to such token. If that - * symbol is from the context that we are popping - * then we are going to generate a dangling pointer. - * We can detect this situation and call again to - * lookup. - */ - if ((yytoken == IDEN || yytoken == TYPEIDEN) && - yylval.sym->ctx == curctx) { - ns = yylval.sym->ns; - dangling = 1; - } - - for (sym = head; sym && sym->ctx == curctx; sym = next) { - /* - * Since we are unlinking them in the inverse order - * we do know that sym is always the head of the - * collision list - */ - next = sym->next; - killsym(sym); - } - head = sym; - - if (--curctx == GLOBALCTX) { - for (sym = labels; sym; sym = next) { - next = sym->next; - killsym(sym); - } - labels = NULL; - } - - if (dangling) { - yylval.sym = lookup(ns, yytext, ALLOC); - yytoken = yylval.sym->token; - } -} - -unsigned -newid(void) -{ - unsigned short id; - - if (lexmode == CPPMODE) - return 0; - id = ++counterid; - if (id == 0) { - die("cc1: overflow in %s identifiers", - (curctx) ? "internal" : "external"); - } - return id; -} - -Symbol * -newsym(int ns, char *name) -{ - Symbol *sym; - - sym = xmalloc(sizeof(*sym)); - if (name) - name = xstrdup(name); - sym->name = name; - sym->id = 0; - sym->hide = 0; - sym->ns = ns; - sym->ctx = curctx; - sym->token = IDEN; - sym->flags = 0; - sym->u.s = NULL; - sym->type = NULL; - sym->hash = NULL; - - if (ns == NS_LABEL) { - sym->next = labels; - labels = sym; - } else if (ns != NS_CPP) { - sym->next = head; - head = sym; - } - return sym; -} - -static Symbol * -linkhash(Symbol *sym) -{ - Symbol **h; - - h = hash(sym->name, sym->ns); - sym->hash = *h; - *h = sym; - - if (sym->ns != NS_CPP) - sym->id = newid(); - sym->flags |= SDECLARED; - return sym; -} - -Symbol * -newstring(char *s, size_t len) -{ - Symbol *sym = newsym(NS_IDEN, NULL); - - if (lexmode != CPPMODE) - sym->type = mktype(chartype, ARY, len, NULL); - sym->id = newid(); - sym->flags |= SSTRING | SCONSTANT | SPRIVATE; - sym->u.s = xmalloc(len); - if (s) - memcpy(sym->u.s, s, len); - - return sym; -} - -Symbol * -newlabel(void) -{ - Symbol *sym = newsym(NS_LABEL, NULL); - sym->id = newid(); - return sym; -} - -Symbol * -lookup(int ns, char *name, int alloc) -{ - Symbol *sym; - int sns, c; - char *t; - - c = *name; - for (sym = *hash(name, ns); sym; sym = sym->hash) { - t = sym->name; - if (*t != c || strcmp(t, name)) - continue; - sns = sym->ns; - if (sns == ns) - return sym; - /* - * When a lookup is done in a namespace associated - * to a struct we also want symbols of NS_IDEN which - * are typedef, because in other case we cannot declare - * fields of such types. - * TODO: Remove this trick - */ - if (sns == NS_KEYWORD || - (sym->flags & STYPEDEF) && ns >= NS_STRUCTS) { - return sym; - } - } - return (alloc == ALLOC) ? newsym(ns, name) : NULL; -} - -Symbol * -install(int ns, Symbol *sym) -{ - if (sym->flags & SDECLARED || sym->ctx != curctx) { - if (sym->ctx == curctx && ns == sym->ns) - return NULL; - sym = newsym(ns, sym->name); - } - return linkhash(sym); -} - -void -keywords(struct keyword *key, int ns) -{ - Symbol *sym; - - for ( ; key->str; ++key) { - sym = linkhash(newsym(ns, key->str)); - sym->token = key->token; - sym->u.token = key->value; - } - /* - * Remove all the predefined symbols from * the symbol list. It - * will make faster some operations. There is no problem of memory - * leakeage because this memory is not ever freed - */ - counterid = 0; - head = NULL; -} - -void -builtins(struct builtin *built) -{ - Symbol *sym; - struct builtin *bp; - - for (bp = built; bp->str; ++bp) { - sym = linkhash(newsym(NS_KEYWORD, bp->str)); - sym->token = BUILTIN; - sym->u.fun = bp->fun; - } - /* - * Remove all the predefined symbols from * the symbol list. It - * will make faster some operations. There is no problem of memory - * leakeage because this memory is not ever freed - */ - counterid = 0; - head = NULL; -} diff --git a/cc1/target/amd64-sysv/arch.c b/cc1/target/amd64-sysv/arch.c @@ -1,220 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/arch/amd64-sysv/arch.c"; - -#include "../../../inc/scc.h" -#include "../../cc1.h" - -#define RANK_BOOL 0 -#define RANK_SCHAR 1 -#define RANK_UCHAR 1 -#define RANK_CHAR 1 -#define RANK_SHORT 2 -#define RANK_USHORT 2 -#define RANK_INT 3 -#define RANK_UINT 3 -#define RANK_LONG 4 -#define RANK_ULONG 4 -#define RANK_LLONG 5 -#define RANK_ULLONG 5 -#define RANK_FLOAT 6 -#define RANK_DOUBLE 7 -#define RANK_LDOUBLE 8 - -/* - * Initializaion of type pointers were done with - * a C99 initilizator '... = &(Type) {...', but - * c compiler in Plan9 gives error with this - * syntax, so I have switched it to this ugly form - * I hope I will change it again in the future - */ - -static Type types[] = { - { /* 0 = voidtype */ - .op = VOID, - .letter = L_VOID, - }, - { /* 1 = pvoidtype */ - .op = PTR, - .letter = L_POINTER, - .prop = TDEFINED, - .type = &types[5], /* chartype */ - .size = 8, - .align = 8, - }, - { /* 2 = booltype */ - .op = INT, - .letter = L_BOOL, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 1, - .align = 1, - .n.rank = RANK_BOOL, - }, - { /* 3 = schartype */ - .op = INT, - .letter = L_INT8, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 1, - .align = 1, - .n.rank = RANK_SCHAR, - }, - { /* 4 = uchartype */ - .op = INT, - .letter = L_UINT8, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 1, - .align = 1, - .n.rank = RANK_UCHAR, - }, - { /* 5 = chartype */ - .op = INT, - .letter = L_INT8, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 1, - .align = 1, - .n.rank = RANK_CHAR, - }, - { /* 6 = ushortype */ - .op = INT, - .letter = L_UINT16, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 2, - .align = 2, - .n.rank = RANK_USHORT, - }, - { /* 7 = shortype */ - .op = INT, - .letter = L_INT16, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 2, - .align = 2, - .n.rank = RANK_SHORT, - }, - { /* 8 = uinttype */ - .op = INT, - .letter = L_UINT32, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 4, - .align = 4, - .n.rank = RANK_UINT, - }, - { /* 9 = inttype */ - .op = INT, - .letter = L_INT32, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 4, - .align = 4, - .n.rank = RANK_INT, - }, - { /* 10 = longtype */ - .op = INT, - .letter = L_INT64, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 8, - .align = 8, - .n.rank = RANK_LONG, - }, - { /* 11 = ulongtype */ - .op = INT, - .letter = L_UINT64, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 8, - .align = 8, - .n.rank = RANK_ULONG, - }, - { /* 12 = ullongtype */ - .op = INT, - .letter = L_UINT64, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 8, - .align = 8, - .n.rank = RANK_ULLONG, - }, - { /* 13 = llongtype */ - .op = INT, - .letter = L_INT64, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 8, - .align = 8, - .n.rank = RANK_LLONG, - }, - { /* 14 = floattype */ - .op = FLOAT, - .letter = L_FLOAT, - .prop = TDEFINED | TARITH, - .size = 4, - .align = 4, - .n.rank = RANK_FLOAT, - }, - { /* 15 = doubletype */ - .op = FLOAT, - .letter = L_DOUBLE, - .prop = TDEFINED | TARITH, - .size = 8, - .align = 8, - .n.rank = RANK_DOUBLE, - }, - { /* 16 = ldoubletype */ - .op = FLOAT, - .letter = L_LDOUBLE, - .prop = TDEFINED | TARITH, - .size = 16, - .align = 16, - .n.rank = RANK_LDOUBLE, - }, - { /* 17 = sizettype */ - .op = INT, - .letter = L_UINT64, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 8, - .align = 8, - .n.rank = RANK_UINT, - }, - { /* 18 = ellipsis */ - .op = ELLIPSIS, - .letter = L_ELLIPSIS, - .prop = TDEFINED, - }, - { /* 19 = pdifftype */ - .op = INT, - .letter = L_INT64, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 8, - .align = 8, - .n.rank = RANK_LONG, - }, - { /* 20 = va_type */ - .op = STRUCT, - .letter = L_VA_ARG, - .prop = TDEFINED, - .size = 24, - .align = 8, - }, -}; - -Type *voidtype = &types[0], *pvoidtype = &types[1], - *booltype = &types[2], *schartype = &types[3], - *uchartype = &types[4], *chartype = &types[5], - *ushortype = &types[6], *shortype = &types[7], - *uinttype = &types[8], *inttype = &types[9], - *longtype = &types[10], *ulongtype = &types[11], - *ullongtype = &types[12], *llongtype = &types[13], - *floattype = &types[14], *doubletype = &types[15], - *ldoubletype = &types[16], - *sizettype = &types[17], *pdifftype = &types[19], - *ellipsistype = &types[18], *va_type = &types[20], - *va_list_type; - -static Symbol dummy0 = {.u.i = 0, .type = &types[9]}, - dummy1 = {.u.i = 1, .type = &types[9]}; -Symbol *zero = &dummy0, *one = &dummy1; - -void -iarch(void) -{ - va_list_type = mktype(va_type, ARY, 1, NULL); -} - -int -valid_va_list(Type *tp) -{ - return tp->op == PTR && eqtype(tp->type, va_type, 1); -} diff --git a/cc1/target/amd64-sysv/arch.mk b/cc1/target/amd64-sysv/arch.mk @@ -1,5 +0,0 @@ - -OBJ-amd64-sysv= $(OBJ) target/amd64-sysv/arch.o - -$(LIBEXEC)/cc1-amd64-sysv: $(OBJ-amd64-sysv) - $(CC) $(SCC_LDFLAGS) $(OBJ-amd64-sysv) -lscc -o $@ diff --git a/cc1/target/arm64-sysv/arch.c b/cc1/target/arm64-sysv/arch.c @@ -1,220 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/arch/arm64-sysv/arch.c"; - -#include "../../../inc/scc.h" -#include "../../cc1.h" - -#define RANK_BOOL 0 -#define RANK_SCHAR 1 -#define RANK_UCHAR 1 -#define RANK_CHAR 1 -#define RANK_SHORT 2 -#define RANK_USHORT 2 -#define RANK_INT 3 -#define RANK_UINT 3 -#define RANK_LONG 4 -#define RANK_ULONG 4 -#define RANK_LLONG 5 -#define RANK_ULLONG 5 -#define RANK_FLOAT 6 -#define RANK_DOUBLE 7 -#define RANK_LDOUBLE 8 - -/* - * Initializaion of type pointers were done with - * a C99 initilizator '... = &(Type) {...', but - * c compiler in Plan9 gives error with this - * syntax, so I have switched it to this ugly form - * I hope I will change it again in the future - */ - -static Type types[] = { - { /* 0 = voidtype */ - .op = VOID, - .letter = L_VOID, - }, - { /* 1 = pvoidtype */ - .op = PTR, - .letter = L_POINTER, - .prop = TDEFINED, - .type = &types[5], /* chartype */ - .size = 8, - .align = 8, - }, - { /* 2 = booltype */ - .op = INT, - .letter = L_BOOL, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 1, - .align = 1, - .n.rank = RANK_BOOL, - }, - { /* 3 = schartype */ - .op = INT, - .letter = L_INT8, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 1, - .align = 1, - .n.rank = RANK_SCHAR, - }, - { /* 4 = uchartype */ - .op = INT, - .letter = L_UINT8, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 1, - .align = 1, - .n.rank = RANK_UCHAR, - }, - { /* 5 = chartype */ - .op = INT, - .letter = L_INT8, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 1, - .align = 1, - .n.rank = RANK_CHAR, - }, - { /* 6 = ushortype */ - .op = INT, - .letter = L_UINT16, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 2, - .align = 2, - .n.rank = RANK_USHORT, - }, - { /* 7 = shortype */ - .op = INT, - .letter = L_INT16, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 2, - .align = 2, - .n.rank = RANK_SHORT, - }, - { /* 8 = uinttype */ - .op = INT, - .letter = L_UINT32, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 4, - .align = 4, - .n.rank = RANK_UINT, - }, - { /* 9 = inttype */ - .op = INT, - .letter = L_INT32, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 4, - .align = 4, - .n.rank = RANK_INT, - }, - { /* 10 = longtype */ - .op = INT, - .letter = L_INT64, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 8, - .align = 8, - .n.rank = RANK_LONG, - }, - { /* 11 = ulongtype */ - .op = INT, - .letter = L_UINT64, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 8, - .align = 8, - .n.rank = RANK_ULONG, - }, - { /* 12 = ullongtype */ - .op = INT, - .letter = L_UINT64, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 8, - .align = 8, - .n.rank = RANK_ULLONG, - }, - { /* 13 = llongtype */ - .op = INT, - .letter = L_INT64, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 8, - .align = 8, - .n.rank = RANK_LLONG, - }, - { /* 14 = floattype */ - .op = FLOAT, - .letter = L_FLOAT, - .prop = TDEFINED | TARITH, - .size = 4, - .align = 4, - .n.rank = RANK_FLOAT, - }, - { /* 15 = doubletype */ - .op = FLOAT, - .letter = L_DOUBLE, - .prop = TDEFINED | TARITH, - .size = 8, - .align = 8, - .n.rank = RANK_DOUBLE, - }, - { /* 16 = ldoubletype */ - .op = FLOAT, - .letter = L_LDOUBLE, - .prop = TDEFINED | TARITH, - .size = 16, - .align = 16, - .n.rank = RANK_LDOUBLE, - }, - { /* 17 = sizettype */ - .op = INT, - .letter = L_UINT64, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 8, - .align = 8, - .n.rank = RANK_UINT, - }, - { /* 18 = ellipsis */ - .op = ELLIPSIS, - .letter = L_ELLIPSIS, - .prop = TDEFINED, - }, - { /* 19 = pdifftype */ - .op = INT, - .letter = L_INT64, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 8, - .align = 8, - .n.rank = RANK_LONG, - }, - { /* 20 = va_type */ - .op = STRUCT, - .letter = L_VA_ARG, - .prop = TDEFINED, - .size = 24, - .align = 8, - }, -}; - -Type *voidtype = &types[0], *pvoidtype = &types[1], - *booltype = &types[2], *schartype = &types[3], - *uchartype = &types[4], *chartype = &types[5], - *ushortype = &types[6], *shortype = &types[7], - *uinttype = &types[8], *inttype = &types[9], - *longtype = &types[10], *ulongtype = &types[11], - *ullongtype = &types[12], *llongtype = &types[13], - *floattype = &types[14], *doubletype = &types[15], - *ldoubletype = &types[16], - *sizettype = &types[17], *pdifftype = &types[19], - *ellipsistype = &types[18], *va_type = &types[20], - *va_list_type; - -static Symbol dummy0 = {.u.i = 0, .type = &types[9]}, - dummy1 = {.u.i = 1, .type = &types[9]}; -Symbol *zero = &dummy0, *one = &dummy1; - -void -iarch(void) -{ - va_list_type = mktype(va_type, ARY, 1, NULL); -} - -int -valid_va_list(Type *tp) -{ - return tp->op == PTR && eqtype(tp->type, va_type, 1); -} diff --git a/cc1/target/arm64-sysv/arch.mk b/cc1/target/arm64-sysv/arch.mk @@ -1,5 +0,0 @@ - -OBJ-arm64-sysv= $(OBJ) target/arm64-sysv/arch.o - -$(LIBEXEC)/cc1-arm64-sysv: $(OBJ-arm64-sysv) - $(CC) $(SCC_LDFLAGS) $(OBJ-arm64-sysv) -lscc -o $@ diff --git a/cc1/target/i386-sysv/arch.c b/cc1/target/i386-sysv/arch.c @@ -1,221 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/arch/i386-sysv/arch.c"; - -#include "../../../inc/scc.h" -#include "../../cc1.h" - -#define RANK_BOOL 0 -#define RANK_SCHAR 1 -#define RANK_UCHAR 1 -#define RANK_CHAR 1 -#define RANK_SHORT 2 -#define RANK_USHORT 2 -#define RANK_INT 3 -#define RANK_UINT 3 -#define RANK_LONG 4 -#define RANK_ULONG 4 -#define RANK_LLONG 5 -#define RANK_ULLONG 5 -#define RANK_FLOAT 6 -#define RANK_DOUBLE 7 -#define RANK_LDOUBLE 8 - -/* - * Initializaion of type pointers were done with - * a C99 initilizator '... = &(Type) {...', but - * c compiler in Plan9 gives error with this - * syntax, so I have switched it to this ugly form - * I hope I will change it again in the future - */ - -static Type types[] = { - { /* 0 = voidtype */ - .op = VOID, - .letter = L_VOID, - }, - { /* 1 = pvoidtype */ - .op = PTR, - .letter = L_POINTER, - .prop = TDEFINED, - .type = &types[5], /* chartype */ - .size = 4, - .align = 4, - }, - { /* 2 = booltype */ - .op = INT, - .letter = L_BOOL, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 1, - .align = 1, - .n.rank = RANK_BOOL, - }, - { /* 3 = schartype */ - .op = INT, - .letter = L_INT8, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 1, - .align = 1, - .n.rank = RANK_SCHAR, - }, - { /* 4 = uchartype */ - .op = INT, - .letter = L_UINT8, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 1, - .align = 1, - .n.rank = RANK_UCHAR, - }, - { /* 5 = chartype */ - .op = INT, - .letter = L_INT8, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 1, - .align = 1, - .n.rank = RANK_CHAR, - }, - { /* 6 = ushortype */ - .op = INT, - .letter = L_UINT16, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 2, - .align = 2, - .n.rank = RANK_USHORT, - }, - { /* 7 = shortype */ - .op = INT, - .letter = L_INT16, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 2, - .align = 2, - .n.rank = RANK_SHORT, - }, - { /* 8 = uinttype */ - .op = INT, - .letter = L_UINT32, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 4, - .align = 4, - .n.rank = RANK_UINT, - }, - { /* 9 = inttype */ - .op = INT, - .letter = L_INT32, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 4, - .align = 4, - .n.rank = RANK_INT, - }, - { /* 10 = longtype */ - .op = INT, - .letter = L_INT32, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 4, - .align = 4, - .n.rank = RANK_LONG, - }, - { /* 11 = ulongtype */ - .op = INT, - .letter = L_UINT32, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 4, - .align = 4, - .n.rank = RANK_ULONG, - }, - { /* 12 = ullongtype */ - .op = INT, - .letter = L_UINT64, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 8, - .align = 4, - .n.rank = RANK_ULLONG, - }, - { /* 13 = llongtype */ - .op = INT, - .letter = L_INT64, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 8, - .align = 4, - .n.rank = RANK_LLONG, - }, - { /* 14 = floattype */ - .op = FLOAT, - .letter = L_FLOAT, - .prop = TDEFINED | TARITH, - .size = 4, - .align = 4, - .n.rank = RANK_FLOAT, - }, - { /* 15 = doubletype */ - .op = FLOAT, - .letter = L_DOUBLE, - .prop = TDEFINED | TARITH, - .size = 8, - .align = 4, - .n.rank = RANK_DOUBLE, - }, - { /* 16 = ldoubletype */ - .op = FLOAT, - .letter = L_LDOUBLE, - .prop = TDEFINED | TARITH, - .size = 12, - .align = 4, - .n.rank = RANK_LDOUBLE, - }, - { /* 17 = sizettype */ - .op = INT, - .letter = L_UINT32, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 4, - .align = 4, - .n.rank = RANK_UINT, - }, - { /* 18 = ellipsis */ - .op = ELLIPSIS, - .letter = L_ELLIPSIS, - .prop = TDEFINED, - }, - { /* 19 = pdifftype */ - .op = INT, - .letter = L_INT32, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 4, - .align = 4, - .n.rank = RANK_INT, - }, - { /* 20 = va_list_type */ - .op = PTR, - .letter = L_POINTER, - .prop = TDEFINED, - .size = 4, - .align = 4, - }, -}; - - -Type *voidtype = &types[0], *pvoidtype = &types[1], - *booltype = &types[2], *schartype = &types[3], - *uchartype = &types[4], *chartype = &types[5], - *ushortype = &types[6], *shortype = &types[7], - *uinttype = &types[8], *inttype = &types[9], - *longtype = &types[10], *ulongtype = &types[11], - *ullongtype = &types[12], *llongtype = &types[13], - *floattype = &types[14], *doubletype = &types[15], - *ldoubletype = &types[16], - *sizettype = &types[17], *pdifftype = &types[19], - *ellipsistype = &types[18], *va_list_type = &types[20]; - - - -static Symbol dummy0 = {.u.i = 0, .type = &types[9]}, - dummy1 = {.u.i = 1, .type = &types[9]}; -Symbol *zero = &dummy0, *one = &dummy1; - -void -iarch(void) -{ -} - -int -valid_va_list(Type *tp) -{ - return eqtype(tp, va_list_type, 1); -} diff --git a/cc1/target/i386-sysv/arch.mk b/cc1/target/i386-sysv/arch.mk @@ -1,5 +0,0 @@ - -OBJ-i386-sysv= $(OBJ) target/i386-sysv/arch.o - -$(LIBEXEC)/cc1-i386-sysv: $(OBJ-i386-sysv) - $(CC) $(SCC_LDFLAGS) $(OBJ-i386-sysv) -lscc -o $@ diff --git a/cc1/target/z80-scc/arch.c b/cc1/target/z80-scc/arch.c @@ -1,219 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/arch/z80/arch.c"; - -#include "../../../inc/scc.h" -#include "../../cc1.h" - -#define RANK_BOOL 0 -#define RANK_SCHAR 1 -#define RANK_UCHAR 1 -#define RANK_CHAR 1 -#define RANK_SHORT 2 -#define RANK_USHORT 2 -#define RANK_INT 3 -#define RANK_UINT 3 -#define RANK_LONG 4 -#define RANK_ULONG 4 -#define RANK_LLONG 5 -#define RANK_ULLONG 5 -#define RANK_FLOAT 6 -#define RANK_DOUBLE 7 -#define RANK_LDOUBLE 8 - -/* - * Initializaion of type pointers were done with - * a C99 initilizator '... = &(Type) {...', but - * c compiler in Plan9 gives error with this - * syntax, so I have switched it to this ugly form - * I hope I will change it again in the future - */ - -static Type types[] = { - { /* 0 = voidtype */ - .op = VOID, - .letter = L_VOID, - }, - { /* 1 = pvoidtype */ - .op = PTR, - .letter = L_POINTER, - .prop = TDEFINED, - .type = &types[5], /* char type */ - .size = 2, - .align = 2, - }, - { /* 2 = booltype */ - .op = INT, - .letter = L_BOOL, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 1, - .align = 1, - .n.rank = RANK_BOOL, - }, - { /* 3 = schartype */ - .op = INT, - .letter = L_INT8, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 1, - .align = 1, - .n.rank = RANK_SCHAR, - }, - { /* 4 = uchartype */ - .op = INT, - .letter = L_UINT8, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 1, - .align = 1, - .n.rank = RANK_UCHAR, - }, - { /* 5 = chartype */ - .op = INT, - .letter = L_UINT8, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 1, - .align = 1, - .n.rank = RANK_CHAR, - }, - { /* 6 = ushortype */ - .op = INT, - .letter = L_UINT16, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 2, - .align = 1, - .n.rank = RANK_USHORT, - }, - { /* 7 = shortype */ - .op = INT, - .letter = L_INT16, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 2, - .align = 1, - .n.rank = RANK_SHORT, - }, - { /* 8 = uinttype */ - .op = INT, - .letter = L_UINT16, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 2, - .align = 1, - .n.rank = RANK_UINT, - }, - { /* 9 = inttype */ - .op = INT, - .letter = L_INT16, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 2, - .align = 1, - .n.rank = RANK_INT, - }, - { /* 10 = longtype */ - .op = INT, - .letter = L_INT32, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 4, - .align = 1, - .n.rank = RANK_LONG, - }, - { /* 11 = ulongtype */ - .op = INT, - .letter = L_UINT32, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 4, - .align = 1, - .n.rank = RANK_ULONG, - }, - { /* 12 = ullongtype */ - .op = INT, - .letter = L_UINT64, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 8, - .align = 1, - .n.rank = RANK_ULLONG, - }, - { /* 13 = llongtype */ - .op = INT, - .letter = L_INT64, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 8, - .align = 1, - .n.rank = RANK_LLONG, - }, - { /* 14 = floattype */ - .op = FLOAT, - .letter = L_FLOAT, - .prop = TDEFINED | TARITH, - .size = 4, - .align = 1, - .n.rank = RANK_FLOAT, - }, - { /* 15 = doubletype */ - .op = FLOAT, - .letter = L_DOUBLE, - .prop = TDEFINED | TARITH, - .size = 8, - .align = 1, - .n.rank = RANK_DOUBLE, - }, - { /* 16 = ldoubletype */ - .op = FLOAT, - .letter = L_LDOUBLE, - .prop = TDEFINED | TARITH, - .size = 16, - .align = 1, - .n.rank = RANK_LDOUBLE, - }, - { /* 17 = sizettype */ - .op = INT, - .letter = L_UINT16, - .prop = TDEFINED | TINTEGER | TARITH, - .size = 2, - .align = 1, - .n.rank = RANK_UINT, - }, - { /* 18 = ellipsis */ - .op = ELLIPSIS, - .letter = L_ELLIPSIS, - .prop = TDEFINED, - }, - { /* 7 = pdifftype */ - .op = INT, - .letter = L_INT16, - .prop = TDEFINED | TINTEGER | TARITH | TSIGNED, - .size = 2, - .align = 1, - .n.rank = RANK_SHORT, - }, - { /* 20 = va_list_type */ - .op = PTR, - .letter = L_POINTER, - .prop = TDEFINED, - .size = 2, - .align = 1, - } -}; - -Type *voidtype = &types[0], *pvoidtype = &types[1], - *booltype = &types[2], *schartype = &types[3], - *uchartype = &types[4], *chartype = &types[5], - *ushortype = &types[6], *shortype = &types[7], - *uinttype = &types[8], *inttype = &types[9], - *longtype = &types[10], *ulongtype = &types[11], - *ullongtype = &types[12], *llongtype = &types[13], - *floattype = &types[14], *doubletype = &types[15], - *ldoubletype = &types[16], - *sizettype = &types[17], *pdifftype = &types[19], - *ellipsistype = &types[18], *va_list_type = &types[20]; - - -static Symbol dummy0 = {.u.i = 0, .type = &types[9]}, - dummy1 = {.u.i = 1, .type = &types[9]}; -Symbol *zero = &dummy0, *one = &dummy1; - -void -iarch(void) -{ -} - -int -valid_va_list(Type *tp) -{ - return eqtype(tp, va_list_type, 1); -} diff --git a/cc1/target/z80-scc/arch.mk b/cc1/target/z80-scc/arch.mk @@ -1,5 +0,0 @@ - -OBJ-z80-scc= $(OBJ) target/z80-scc/arch.o - -$(LIBEXEC)/cc1-z80-scc: $(OBJ-z80-scc) - $(CC) $(SCC_LDFLAGS) $(OBJ-z80-scc) -lscc -o $@ diff --git a/cc1/types.c b/cc1/types.c @@ -1,438 +0,0 @@ -static char sccsid[] = "@(#) ./cc1/types.c"; -#include <assert.h> -#include <inttypes.h> -#include <stdlib.h> -#include <string.h> - -#include <cstd.h> -#include "../inc/scc.h" -#include "cc1.h" - -#define NR_TYPE_HASH 16 -#define HASH(t) (((t)->op ^ (uintptr_t) (t)->type>>3) & NR_TYPE_HASH-1) - -static Type *typetab[NR_TYPE_HASH], *localtypes; - -/* FIXME: - * Compiler can generate warnings here if the ranges of TINT, - * TUINT and TFLOAT are smaller than any of the constants in this - * array. Ignore them if you know that the target types are correct - */ -static struct limits limits[][4] = { - { - { /* 0 = unsigned 1 byte */ - .min.i = 0, - .max.i = 0xff - }, - { /* 1 = unsigned 2 bytes */ - .min.i = 0, - .max.i = 0xffff - }, - { /* 2 = unsigned 4 bytes */ - .min.i = 0, - .max.i = 0xffffffff - }, - { /* 3 = unsigned 8 bytes */ - .min.i = 0, - .max.i = 0xffffffffffffffff - } - }, - { - { /* 0 = signed 1 byte */ - .min.i = -0x7f-1, - .max.i = 0x7f - }, - { /* 1 = signed 2 byte */ - .min.i = -0x7fff-1, - .max.i = 0x7fff - }, - { /* 2 = signed 4 byte */ - .min.i = -0x7fffffff-1, - .max.i = 0x7fffffff - }, - { /* 3 = signed 8 byte */ - .min.i = -0x7fffffffffffffff-1, - .max.i = 0x7fffffffffffffff, - } - }, - { - { - /* 0 = float 4 bytes */ - .min.f = -1, - .max.f = 2 - }, - { - /* 1 = float 8 bytes */ - .min.f = -1, - .max.f = 2, - }, - { - /* 2 = float 16 bytes */ - .min.f = -1, - .max.f = 2, - } - } -}; - -struct limits * -getlimits(Type *tp) -{ - int ntable, ntype; - - switch (tp->op) { - case ENUM: - case INT: - ntable = ((tp->prop & TSIGNED) != 0); - switch (tp->size) { - case 1: ntype = 0; break; - case 2: ntype = 1; break; - case 4: ntype = 2; break; - case 8: ntype = 3; break; - } - break; - case FLOAT: - ntable = 2; - switch (tp->size) { - case 4: ntype = 0; break; - case 8: ntype = 1; break; - case 16: ntype = 2; break; - } - break; - default: - abort(); - } - - return &limits[ntable][ntype]; -} - -Type * -ctype(int type, int sign, int size) -{ - switch (type) { - case CHAR: - if (size) - goto invalid_type; - switch (sign) { - case 0: - return chartype; - case SIGNED: - return schartype; - case UNSIGNED: - return uchartype; - } - break; - case VA_LIST: - if (size || sign) - goto invalid_type; - return va_list_type; - case VOID: - if (size || sign) - goto invalid_type; - return voidtype; - case BOOL: - if (size || sign) - goto invalid_type; - return booltype; - case 0: - case INT: - switch (size) { - case 0: - return (sign == UNSIGNED) ? uinttype : inttype; - case SHORT: - return (sign == UNSIGNED) ? ushortype : shortype; - case LONG: - return (sign == UNSIGNED) ? ulongtype : longtype; - case LLONG: - return (sign == UNSIGNED) ? ullongtype : llongtype; - } - break; - case DOUBLE: - if (size == LLONG) - goto invalid_type; - if (size == LONG) - size = LLONG; - else - size = LONG; - goto floating; - case FLOAT: - if (size == LLONG) - goto invalid_type; - floating: - if (sign) - goto invalid_type; - switch (size) { - case 0: - return floattype; - case LONG: - return doubletype; - case LLONG: - return ldoubletype; - } - break; - } - -invalid_type: - error("invalid type specification"); -} - -void -typesize(Type *tp) -{ - Symbol **sp; - Type *type; - unsigned long size, offset; - int align, a; - TINT n; - - switch (tp->op) { - case ARY: - /* FIXME: Control overflow */ - tp->size = tp->n.elem * tp->type->size; - tp->align = tp->type->align; - return; - case PTR: - tp->size = pvoidtype->size; - tp->align = pvoidtype->align; - return; - case STRUCT: - case UNION: - /* FIXME: Control overflow */ - /* - * The alignment of the struct/union is - * he alignment of the largest included type. - * The size of an union is the size of the largest - * field, and the size of a struct is the sum - * of the size of every field plus padding bits. - */ - offset = align = size = 0; - n = tp->n.elem; - for (sp = tp->p.fields; n--; ++sp) { - (*sp)->u.i = offset; - type = (*sp)->type; - a = type->align; - if (a > align) - align = a; - if (tp->op == STRUCT) { - if (--a != 0) - size = (size + a) & ~a; - size += type->size; - offset = size; - } else { - if (type->size > size) - size = type->size; - } - } - - tp->align = align; - /* - * We have to add the padding bits to - * ensure next struct in an array is well - * alignment. - */ - if (tp->op == STRUCT && align-- > 1) - size += size+align & ~align; - tp->size = size; - return; - case ENUM: - tp->size = inttype->size; - tp->align = inttype->align; - return; - case FTN: - return; - default: - abort(); - } -} - -Type * -deftype(Type *tp) -{ - tp->prop |= TDEFINED; - typesize(tp); - emit(OTYP, tp); - return tp; -} - -static Type * -newtype(Type *base) -{ - Type *tp; - size_t siz; - - tp = xmalloc(sizeof(*tp)); - *tp = *base; - tp->id = newid(); - - if (tp->op == FTN) { - siz = tp->n.elem * sizeof(Type *); - tp->p.pars = memcpy(xmalloc(siz), tp->p.pars, siz); - } - - if (curfun) { - /* it is a type defined in the body of a function */ - tp->next = localtypes; - localtypes = tp; - } - if (tp->prop & TDEFINED) - deftype(tp); - return tp; -} - -Type * -mktype(Type *tp, int op, TINT nelem, Type *pars[]) -{ - Type **tbl, type; - Type *bp; - - if (op == PTR && tp == voidtype) - return pvoidtype; - - memset(&type, 0, sizeof(type)); - type.type = tp; - type.op = op; - type.p.pars = pars; - type.n.elem = nelem; - - switch (op) { - case ARY: - if (tp == voidtype) { - errorp("declaration of array of voids type"); - tp = inttype; - } - type.letter = L_ARRAY; - if (nelem != 0) - type.prop |= TDEFINED; - break; - case KRFTN: - type.prop |= TDEFINED | TK_R; - type.op = FTN; - type.letter = L_FUNCTION; - break; - case FTN: - if (nelem > 0 && pars[nelem-1] == ellipsistype) - type.prop |= TELLIPSIS; - type.letter = L_FUNCTION; - type.prop |= TDEFINED; - break; - case PTR: - type.letter = L_POINTER; - type.prop |= TDEFINED; - break; - case ENUM: - type.letter = inttype->letter; - type.prop |= TINTEGER | TARITH; - type.n.rank = inttype->n.rank; - goto create_type; - case STRUCT: - type.letter = L_STRUCT; - type.prop |= TAGGREG; - goto create_type; - case UNION: - type.letter = L_UNION; - type.prop |= TAGGREG; - create_type: - return newtype(&type); - default: - abort(); - } - - tbl = &typetab[HASH(&type)]; - for (bp = *tbl; bp; bp = bp->h_next) { - if (eqtype(bp, &type, 0)) - return bp; - } - - bp = newtype(&type); - bp->h_next = *tbl; - *tbl = bp; - - return bp; -} - -int -eqtype(Type *tp1, Type *tp2, int equiv) -{ - TINT n; - Type **p1, **p2; - Symbol **s1, **s2; - - if (tp1 == tp2) - return 1; - if (!tp1 || !tp2) - return 0; - if (tp1->op != tp2->op) - return 0; - - switch (tp1->op) { - case UNION: - case STRUCT: - if (tp1->letter != tp2->letter) - return 0; - if (tp1->tag->name || tp2->tag->name) - return tp1->tag == tp2->tag; - if (tp1->n.elem != tp2->n.elem) - return 0; - s1 = tp1->p.fields, s2 = tp2->p.fields; - for (n = tp1->n.elem; n > 0; --n, ++s1, ++s2) { - if (strcmp((*s1)->name, (*s2)->name)) - return 0; - if (!eqtype((*s1)->type, (*s2)->type, equiv)) - return 0; - } - return 1; - case FTN: - if (tp1->n.elem != tp2->n.elem) - return 0; - p1 = tp1->p.pars, p2 = tp2->p.pars; - for (n = tp1->n.elem; n > 0; --n) { - if (!eqtype(*p1++, *p2++, equiv)) - return 0; - } - goto check_base; - case ARY: - if (equiv && (tp1->n.elem == 0 || tp2->n.elem == 0)) - goto check_base; - if (tp1->n.elem != tp2->n.elem) - return 0; - case PTR: - check_base: - return eqtype(tp1->type, tp2->type, equiv); - case VOID: - case ENUM: - return 0; - case INT: - case FLOAT: - return tp1->letter == tp2->letter; - default: - abort(); - } -} - -void -flushtypes(void) -{ - Type *tp, *next, **h; - - for (tp = localtypes; tp; tp = next) { - next = tp->next; - switch (tp->op) { - default: - /* - * All the local types are linked after - * global types, and since we are - * unlinking them in the inverse order - * we do know that tp is always the head - * of the collision list - */ - h = &typetab[HASH(tp)]; - assert(*h == tp); - *h = tp->h_next; - case STRUCT: - case UNION: - case ENUM: - free(tp); - break; - } - } - localtypes = NULL; -} diff --git a/cc2/Makefile b/cc2/Makefile @@ -1,35 +0,0 @@ -.POSIX: - -PROJECTDIR = .. -include $(PROJECTDIR)/rules.mk -include $(LIBSCC)/libdep.mk - -MORECFLAGS = -I$(PROJECTDIR)/inc/$(STD) - -OBJ = main.o parser.o peep.o symbol.o node.o code.o optm.o - -TARGETS = $(LIBEXEC)/cc2-amd64-sysv $(LIBEXEC)/cc2-i386-sysv \ - $(LIBEXEC)/cc2-qbe_amd64-sysv $(LIBEXEC)/cc2-z80-scc - -all: $(TARGETS) - -$(TARGETS): $(LIBDIR)/libscc.a - -dep: - $(PROJECTDIR)/mkdep.sh - -error.h: cc2.h - rm -f $@; trap 'rm -f $$$$.h' EXIT INT QUIT ;\ - awk -f generror.awk cc2.h > $$$$.h && mv $$$$.h $@ - -clean: - rm -f *.o error.h - rm -f target/*/*.o - rm -f $(TARGETS) - -include target/amd64-sysv/target.mk -include target/i386-sysv/target.mk -include target/qbe_amd64-sysv/target.mk -include target/qbe_arm64-sysv/target.mk -include target/z80-scc/target.mk -include deps.mk diff --git a/cc2/code.c b/cc2/code.c @@ -1,133 +0,0 @@ -static char sccsid[] = "@(#) ./cc2/code.c"; -#include <stdlib.h> -#include <string.h> - -#include "../inc/scc.h" -#include "cc2.h" - -Inst *pc, *prog; - -static void -nextpc(void) -{ - Inst *new; - - new = xcalloc(1, sizeof(*new)); /* TODO: create an arena */ - - if (!pc) { - prog = new; - } else { - new->next = pc->next; - pc->next = new; - } - - /* SNONE being 0, calloc initialized {from1,from2,to}.kind for us */ - new->prev = pc; - pc = new; -} - -static void -addr(Node *np, Addr *addr) -{ - Symbol *sym; - - switch (np->op) { - case OREG: - /* TODO: - * At this moment this op is used also for register variables - */ - addr->kind = SREG; - addr->u.reg = np->u.reg; - break; - case OCONST: - addr->kind = SCONST; - /* TODO: Add support for more type of constants */ - addr->u.i = np->u.i; - break; - case OTMP: - case OLABEL: - case OAUTO: - case OMEM: - sym = np->u.sym; - addr->kind = sym->kind; - addr->u.sym = sym; - break; - default: - abort(); - } -} - -Symbol * -newlabel(void) -{ - Symbol *sym = getsym(TMPSYM); - - sym->kind = SLABEL; - return sym; -} - -Node * -label2node(Node *np, Symbol *sym) -{ - if(!sym) - sym = newlabel(); - if (!np) - np = node(OLABEL); - np->op = OLABEL; - np->u.sym = sym; - - return np; -} - -Node * -constnode(Node *np, TUINT n, Type *tp) -{ - if (!np) - np = node(OCONST); - np->op = OCONST; - np->left = NULL; - np->right = NULL; - np->type = *tp; - np->u.i = n; - return np; -} - -void -setlabel(Symbol *sym) -{ - if (!sym) - return; - code(0, NULL, NULL, NULL); - pc->label = sym; - sym->u.inst = pc; -} - -void -code(int op, Node *to, Node *from1, Node *from2) -{ - nextpc(); - if (from1) - addr(from1, &pc->from1); - if (from2) - addr(from2, &pc->from2); - if (to) - addr(to, &pc->to); - pc->op = op; -} - -void -delcode(void) -{ - Inst *prev = pc->prev, *next = pc->next; - - free(pc); - if (!prev) { - pc = next; - prog = NULL; - } else { - pc = prev; - prev->next = next; - if (next) - next->prev = prev; - } -} diff --git a/cc2/deps.mk b/cc2/deps.mk @@ -1,61 +0,0 @@ -parser.c: $(PROJECTDIR)/inc/$(STD)/cstd.h -target/amd64-sysv/code.o: $(INCLUDE)/$(STD)/cstd.h -target/i386-sysv/code.o: $(INCLUDE)/$(STD)/cstd.h -target/qbe/cgen.o: $(INCLUDE)/$(STD)/cstd.h -target/z80-scc/code.o: $(INCLUDE)/$(STD)/cstd.h - -#deps -code.o: ../inc/scc.h -code.o: cc2.h -main.o: ../inc/arg.h -main.o: ../inc/scc.h -main.o: cc2.h -main.o: error.h -node.o: ../inc/scc.h -node.o: cc2.h -optm.o: ../inc/scc.h -optm.o: cc2.h -parser.o: ../inc/scc.h -parser.o: cc2.h -peep.o: ../inc/scc.h -peep.o: cc2.h -symbol.o: ../inc/scc.h -symbol.o: cc2.h -target/amd64-sysv/cgen.o: target/amd64-sysv/../../../inc/scc.h -target/amd64-sysv/cgen.o: target/amd64-sysv/../../cc2.h -target/amd64-sysv/cgen.o: target/amd64-sysv/arch.h -target/amd64-sysv/code.o: target/amd64-sysv/../../../inc/scc.h -target/amd64-sysv/code.o: target/amd64-sysv/../../cc2.h -target/amd64-sysv/code.o: target/amd64-sysv/arch.h -target/amd64-sysv/optm.o: target/amd64-sysv/../../../inc/scc.h -target/amd64-sysv/optm.o: target/amd64-sysv/../../cc2.h -target/amd64-sysv/types.o: target/amd64-sysv/../../../inc/scc.h -target/amd64-sysv/types.o: target/amd64-sysv/../../cc2.h -target/i386-sysv/cgen.o: target/i386-sysv/../../../inc/scc.h -target/i386-sysv/cgen.o: target/i386-sysv/../../cc2.h -target/i386-sysv/cgen.o: target/i386-sysv/arch.h -target/i386-sysv/code.o: target/i386-sysv/../../../inc/scc.h -target/i386-sysv/code.o: target/i386-sysv/../../cc2.h -target/i386-sysv/code.o: target/i386-sysv/arch.h -target/i386-sysv/optm.o: target/i386-sysv/../../../inc/scc.h -target/i386-sysv/optm.o: target/i386-sysv/../../cc2.h -target/i386-sysv/types.o: target/i386-sysv/../../../inc/scc.h -target/i386-sysv/types.o: target/i386-sysv/../../cc2.h -target/qbe/cgen.o: target/qbe/../../../inc/scc.h -target/qbe/cgen.o: target/qbe/../../cc2.h -target/qbe/cgen.o: target/qbe/arch.h -target/qbe/code.o: target/qbe/../../../inc/scc.h -target/qbe/code.o: target/qbe/../../cc2.h -target/qbe/code.o: target/qbe/arch.h -target/qbe/optm.o: target/qbe/../../../inc/scc.h -target/qbe/optm.o: target/qbe/../../cc2.h -target/z80-scc/cgen.o: target/z80-scc/../../../inc/scc.h -target/z80-scc/cgen.o: target/z80-scc/../../cc2.h -target/z80-scc/cgen.o: target/z80-scc/arch.h -target/z80-scc/code.o: target/z80-scc/../../../inc/scc.h -target/z80-scc/code.o: target/z80-scc/../../cc2.h -target/z80-scc/code.o: target/z80-scc/arch.h -target/z80-scc/optm.o: target/z80-scc/../../../inc/scc.h -target/z80-scc/optm.o: target/z80-scc/../../cc2.h -target/z80-scc/types.o: target/z80-scc/../../../inc/scc.h -target/z80-scc/types.o: target/z80-scc/../../cc2.h diff --git a/cc2/main.c b/cc2/main.c @@ -1,70 +0,0 @@ -static char sccsid[] = "@(#) ./cc2/main.c"; - -#include <errno.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "../inc/arg.h" -#include "../inc/scc.h" -#include "cc2.h" -#include "error.h" - -char *argv0; - -void -error(unsigned nerror, ...) -{ - va_list va; - va_start(va, nerror); - vfprintf(stderr, errlist[nerror], va); - va_end(va); - putc('\n', stderr); - exit(1); -} - -static int -moreinput(void) -{ - int c; - -repeat: - if (feof(stdin)) - return 0; - if ((c = getchar()) == '\n' || c == EOF) - goto repeat; - ungetc(c, stdin); - return 1; -} - -static void -usage(void) -{ - fputs("usage: cc2 [irfile]\n", stderr); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - ARGBEGIN { - default: - usage(); - } ARGEND - - if (argv[0] && !freopen(argv[0], "r", stdin)) - die("cc2: %s: %s", argv[0], strerror(errno)); - - while (moreinput()) { - parse(); - apply(optm_ind); - apply(optm_dep); - apply(sethi); - apply(cgen); - getbblocks(); /* TODO: run apply over asm ins too */ - peephole(); - writeout(); - } - return 0; -} diff --git a/cc2/node.c b/cc2/node.c @@ -1,142 +0,0 @@ -static char sccsid[] = "@(#) ./cc2/node.c"; -#include <stdlib.h> -#include <string.h> - -#include "../inc/scc.h" - -#include "cc2.h" - -#define NNODES 32 - -Node *curstmt; -Symbol *curfun; - -static Alloc *arena; - - -Node * -node(int op) -{ - struct arena *ap; - Node *np; - - if (!arena) - arena = alloc(sizeof(Node), NNODES); - np = memset(new(arena), 0, sizeof(*np)); - np->op = op; - - return np; -} - -#ifndef NDEBUG -#include <stdio.h> - -static void -prnode(Node *np) -{ - if (np->left) - prnode(np->left); - if (np->right) - prnode(np->right); - fprintf(stderr, "\t%c%lu", np->op, np->type.size); -} - -void -prtree(Node *np) -{ - prnode(np); - putc('\n', stderr); -} - -void -prforest(char *msg) -{ - Node *np; - - if (!curfun) - return; - - fprintf(stderr, "%s {\n", msg); - for (np = curfun->u.stmt; np; np = np->next) - prtree(np); - fputs("}\n", stderr); -} -#endif - -Node * -addstmt(Node *np, int flag) -{ - if (curstmt) - np->next = curstmt->next; - np->prev = curstmt; - - if (!curfun->u.stmt) - curfun->u.stmt = np; - else - curstmt->next = np; - - if (flag == SETCUR) - curstmt = np; - - return np; -} - -Node * -delstmt(void) -{ - Node *next, *prev; - - next = curstmt->next; - prev = curstmt->prev; - if (next) - next->prev = prev; - if (prev) - prev->next = next; - else - curfun->u.stmt = next; - deltree(curstmt); - - return curstmt = next; -} - -Node * -nextstmt(void) -{ - return curstmt = curstmt->next; -} - -void -delnode(Node *np) -{ - delete(arena, np); -} - -void -deltree(Node *np) -{ - if (!np) - return; - deltree(np->left); - deltree(np->right); - delnode(np); -} - -void -cleannodes(void) -{ - if (arena) { - dealloc(arena); - arena = NULL; - } - curstmt = NULL; -} - -void -apply(Node *(*fun)(Node *)) -{ - if (!curfun) - return; - curstmt = curfun->u.stmt; - while (curstmt) - (*fun)(curstmt) ? nextstmt() : delstmt(); -} diff --git a/cc2/optm.c b/cc2/optm.c @@ -1,9 +0,0 @@ -#include "../inc/scc.h" -#include "cc2.h" - -Node * -optm_ind(Node *np) -{ - return np; -} - diff --git a/cc2/parser.c b/cc2/parser.c @@ -1,722 +0,0 @@ -static char sccsid[] = "@(#) ./cc2/parser.c"; -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <cstd.h> -#include "../inc/scc.h" - -#include "cc2.h" - -#define STACKSIZ 50 - -extern Type int8type, int16type, int32type, int64type, - uint8type, uint16type, uint32type, uint64type, - float32type, float64type, float80type, - booltype, - ptrtype, - voidtype, - arg_type; - -Type funetype = { - .flags = FUNF | ELLIPS -}; - -Type funtype = { - .flags = FUNF -}; - -union tokenop { - void *arg; - unsigned op; -}; - -struct swtch { - int nr; - Node *first; - Node *last; -}; - -static struct swtch swtbl[NR_BLOCK], *swp = swtbl; -static Symbol *lastfun; - -typedef void parsefun(char *, union tokenop); -static parsefun type, symbol, getname, unary, binary, ternary, call, - constant, composed, binit, einit, - jump, oreturn, loop, assign, - ocase, bswitch, eswitch, builtin; - -typedef void evalfun(void); -static evalfun vardecl, beginfun, endfun, endpars, stmt, - array, aggregate, flddecl, labeldcl; - -static struct decoc { - void (*eval)(void); - void (*parse)(char *token, union tokenop); - union tokenop u; -} optbl[] = { /* eval parse args */ - ['A'] = { vardecl, symbol, .u.op = SAUTO<<8 | OAUTO}, - ['R'] = { vardecl, symbol, .u.op = SREG<<8 | OREG}, - ['G'] = { vardecl, symbol, .u.op = SGLOB<<8 | OMEM}, - ['X'] = { vardecl, symbol, .u.op = SEXTRN<<8 | OMEM}, - ['Y'] = { vardecl, symbol, .u.op = SPRIV<<8 | OMEM}, - ['T'] = { vardecl, symbol, .u.op = SLOCAL<<8 | OMEM}, - ['M'] = { flddecl, symbol, .u.op = SMEMB<<8 | OMEM}, - ['L'] = { labeldcl, symbol, .u.op = SLABEL<<8 | OLABEL}, - - ['C'] = { NULL, type, .u.arg = &int8type}, - ['I'] = { NULL, type, .u.arg = &int16type}, - ['W'] = { NULL, type, .u.arg = &int32type}, - ['Q'] = { NULL, type, .u.arg = &int64type}, - ['K'] = { NULL, type, .u.arg = &uint8type}, - ['N'] = { NULL, type, .u.arg = &uint16type}, - ['Z'] = { NULL, type, .u.arg = &uint32type}, - ['O'] = { NULL, type, .u.arg = &uint64type}, - ['J'] = { NULL, type, .u.arg = &float32type}, - ['D'] = { NULL, type, .u.arg = &float64type}, - ['H'] = { NULL, type, .u.arg = &float80type}, - ['0'] = { NULL, type, .u.arg = &voidtype}, - ['B'] = { NULL, type, .u.arg = &booltype}, - ['P'] = { NULL, type, .u.arg = &ptrtype}, - ['E'] = { NULL, type, .u.arg = &funetype}, - ['1'] = { NULL, type, .u.arg = &arg_type}, - - ['F'] = { NULL, type, .u.arg = &funtype}, - ['V'] = { array,composed, 0}, - ['U'] = {aggregate,composed, 0}, - ['S'] = {aggregate,composed, 0}, - - ['"'] = { NULL, getname, 0}, - ['{'] = { beginfun, NULL, 0}, - ['}'] = { endfun, NULL, 0}, - ['('] = { NULL, binit, 0}, - [')'] = { NULL, einit, 0}, - ['\\'] = { endpars, NULL, 0}, - ['\t'] = { stmt, NULL, 0}, - - ['~'] = { NULL, unary, .u.op = OCPL}, - ['_'] = { NULL, unary, .u.op = OSNEG}, - ['\''] = { NULL, unary, .u.op = OADDR}, - ['@'] = { NULL, unary, .u.op = OPTR}, - ['g'] = { NULL, unary, .u.op = OCAST}, - ['p'] = { NULL, unary, .u.op = OPAR}, - ['n'] = { NULL, unary, .u.op = ONEG}, - - ['a'] = { NULL, binary, .u.op = OAND}, - ['o'] = { NULL, binary, .u.op = OOR}, - ['.'] = { NULL, binary, .u.op = OFIELD}, - ['+'] = { NULL, binary, .u.op = OADD}, - ['-'] = { NULL, binary, .u.op = OSUB}, - ['*'] = { NULL, binary, .u.op = OMUL}, - ['%'] = { NULL, binary, .u.op = OMOD}, - ['/'] = { NULL, binary, .u.op = ODIV}, - ['l'] = { NULL, binary, .u.op = OSHL}, - ['r'] = { NULL, binary, .u.op = OSHR}, - ['<'] = { NULL, binary, .u.op = OLT}, - ['>'] = { NULL, binary, .u.op = OGT}, - ['['] = { NULL, binary, .u.op = OLE}, - [']'] = { NULL, binary, .u.op = OGE}, - ['='] = { NULL, binary, .u.op = OEQ}, - ['!'] = { NULL, binary, .u.op = ONE}, - ['&'] = { NULL, binary, .u.op = OBAND}, - ['|'] = { NULL, binary, .u.op = OBOR}, - ['^'] = { NULL, binary, .u.op = OBXOR}, - [','] = { NULL, binary, .u.op = OCOMMA}, - ['m'] = { NULL, builtin,.u.op = OBUILTIN}, - - [':'] = { NULL, assign, .u.op = OASSIG}, - ['?'] = { NULL, ternary, .u.op = OASK}, - ['c'] = { NULL, call, .u.op = OCALL}, - ['z'] = { NULL, call, .u.op = OCALLE}, - - ['#'] = { NULL,constant, .u.op = OCONST}, - - ['j'] = { NULL, jump, .u.op = OJMP}, - ['y'] = { NULL, jump, .u.op = OBRANCH}, - ['h'] = { NULL, oreturn, .u.op = ORET}, - ['i'] = { NULL, NULL, .u.op = OINC}, - ['d'] = { NULL, NULL, .u.op = ODEC}, - - ['b'] = { NULL, loop, .u.op = OBLOOP}, - ['e'] = { NULL, loop, .u.op = OELOOP}, - - ['v'] = { NULL, ocase, .u.op = OCASE}, - ['f'] = { NULL, ocase, .u.op = ODEFAULT}, - ['t'] = { NULL, eswitch, .u.op = OESWITCH}, - ['s'] = { NULL, bswitch, .u.op = OBSWITCH}, -}; - -static int sclass, inpars, ininit, endf, lineno; -static void *stack[STACKSIZ], **sp = stack; - -static Node * -push(void *elem) -{ - if (sp == &stack[STACKSIZ]) - error(ESTACKO); - return *sp++ = elem; -} - -static void * -pop(void) -{ - if (sp == stack) - error(ESTACKU); - return *--sp; -} - -static int -empty(void) -{ - return sp == stack; -} - -static void -type(char *token, union tokenop u) -{ - push(u.arg); -} - -static void -composed(char *token, union tokenop u) -{ - Symbol *sym; - - sym = getsym(atoi(token+1)); - push(&sym->type); -} - -static void -getname(char *t, union tokenop u) -{ - push((*++t) ? xstrdup(t) : NULL); -} - -static void -symbol(char *token, union tokenop u) -{ - Node *np = node(u.op & 0xFF); - Symbol *sym = getsym(atoi(token+1)); - - sclass = u.op >> 8; - np->u.sym = sym; - np->type = sym->type; - push(np); -} - -static Type * -gettype(char *token) -{ - struct decoc *dp; - - dp = &optbl[*token]; - if (!dp->parse) - error(ESYNTAX); - (*dp->parse)(token, dp->u); - return pop(); -} - -static void -constant(char *token, union tokenop u) -{ - static char letters[] = "0123456789ABCDEF"; - Node *np; - TUINT v; - unsigned c; - - ++token; - if (*token == '"') { - ++token; - np = node(OSTRING); - np->type.flags = STRF; - np->type.size = strlen(token); - np->type.align = int8type.align; - np->u.s = xstrdup(token); - } else { - np = node(OCONST); - np->type = *gettype(token++); - for (v = 0; c = *token++; v += c) { - v <<= 4; - c = strchr(letters, c) - letters; - } - np->u.i = v; - } - push(np); -} - -static void -assign(char *token, union tokenop u) -{ - int subop; - Node *np = node(u.op); - - switch (subop = *++token) { - case '+': - case '-': - case '*': - case '%': - case '/': - case 'l': - case 'r': - case '&': - case '|': - case '^': - case 'i': - case 'd': - ++token; - subop = optbl[subop].u.op; - break; - default: - subop = 0; - break; - } - - np->u.subop = subop; - np->type = *gettype(token); - np->right = pop(); - np->left = pop(); - push(np); -} - -static void -ternary(char *token, union tokenop u) -{ - Node *ask = node(OASK), *colon = node(OCOLON); - Type *tp = gettype(token+1); - - colon->right = pop(); - colon->left = pop(); - - ask->type = *tp; - ask->left = pop(); - ask->right = colon; - push(ask); -} - -static void -eval(char *tok) -{ - struct decoc *dp; - - do { - dp = &optbl[*tok]; - if (!dp->parse) - break; - (*dp->parse)(tok, dp->u); - } while (tok = strtok(NULL, "\t\n")); -} - -static int -nextline(void) -{ - static char line[LINESIZ]; - size_t len; - int c; - void (*fun)(void); - -repeat: - ++lineno; - if (!fgets(line, sizeof(line), stdin)) - return 0; - if ((len = strlen(line)) == 0 || line[0] == '\n') - goto repeat; - if (line[len-1] != '\n') - error(len < sizeof(line)-1 ? ELNBLNE : ELNLINE); - line[len-1] = '\0'; - - c = *line; - eval(strtok(line, "\t\n")); - if ((fun = *optbl[c].eval) != NULL) - (*fun)(); - if (sp != stack) - error(ESTACKA); - return 1; -} - -static void -oreturn(char *token, union tokenop u)