From: kbongers Date: Wed, 24 Oct 2001 20:09:53 +0000 (+0000) Subject: remove cpp directory X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=bdc517ae4a26d2047e7379cbd7d94b2ab665c2df;p=fw%2Fsdcc remove cpp directory git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1443 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/support/cpp/Makefile.bcc b/support/cpp/Makefile.bcc deleted file mode 100644 index a1cad79c..00000000 --- a/support/cpp/Makefile.bcc +++ /dev/null @@ -1,43 +0,0 @@ -VERSION = 2.2.0 -VERSIONHI = 2 -VERSIONLO = 2 -VERSIONP = 0 - -PRJDIR = ..\.. - -srcdir = . -prefix = /cygnus/cygwin-b20/kvigor/ -exec_prefix = ${prefix} -bindir = ${exec_prefix}/bin -libdir = ${exec_prefix}/lib -datadir = ${prefix}/share -includedir = ${prefix}/include -mandir = ${prefix}/man -man1dir = $(mandir)/man1 -man2dir = $(mandir)/man2 -infodir = ${prefix}/info - -STD_INC = @sdcc_include_dir@ -!include ..\..\bcc.inc -CFLAGS = -I. -I$(PRJDIR) -D_FORASXXXX_ -M_OR_MM = -MM -LDFLAGS = - -OBJECTS = cppalloc.obj cpperror.obj cppexp.obj cpphash.obj cpplib.obj cppmain.obj - -SLIBOBJS = $(SLIB)\NewAlloc.obj - -TARGET = $(PRJDIR)\bin\sdcppold.exe - - -# Compiling entire program or any subproject -# ------------------------------------------ -all: $(TARGET) - -$(TARGET): $(SLIBOBJS) $(OBJECTS) - bcc32 -e$(TARGET) $(OBJECTS) $(SLIBOBJS) - -!include Makefile.dep - - -# End of cpp/Makefile diff --git a/support/cpp/Makefile.in b/support/cpp/Makefile.in deleted file mode 100644 index f949d890..00000000 --- a/support/cpp/Makefile.in +++ /dev/null @@ -1,109 +0,0 @@ -# -# -# - -VERSION = @VERSION@ -VERSIONHI = @VERSIONHI@ -VERSIONLO = @VERSIONLO@ -VERSIONP = @VERSIONP@ - -SHELL = /bin/sh -CC = @CC@ -CPP = @CPP@ -INSTALL = @INSTALL@ -STRIP = @STRIP@ - -# Source library - -SLIB = ../Util - -PRJDIR = ../.. - -srcdir = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -libdir = @libdir@ -datadir = @datadir@ -includedir = @includedir@ -mandir = @mandir@ -man1dir = $(mandir)/man1 -man2dir = $(mandir)/man2 -infodir = @infodir@ - -STD_INC = @sdcc_include_dir@ -CPPFLAGS = @CPPFLAGS@ -I. -I$(PRJDIR) -I$(SLIB) -D_FORASXXXX_ -CFLAGS = @CFLAGS@ -M_OR_MM = @M_OR_MM@ -LDFLAGS = @LDFLAGS@ @LIBS@ - -SLIBOBJS = NewAlloc.o - -OBJECTS = cppalloc.o cpperror.o cppexp.o cpphash.o cpplib.o cppmain.o support.o -SOURCES = $(patsubst %.o,%.c,$(OBJECTS)) - -TARGET = $(PRJDIR)/bin/sdcppold - -transform = @program_transform_name@ - -# Compiling entire program or any subproject -# ------------------------------------------ -all: checkconf $(TARGET) - -$(TARGET): $(SLIBOBJS) $(OBJECTS) - $(CC) $(LDFLAGS) -o $@ $(SLIBOBJS) $(OBJECTS) - -# Compiling and installing everything and runing test -# --------------------------------------------------- -install: all installdirs - $(INSTALL) $(TARGET) `echo $(bindir)/sdcppold|sed '$(transform)'` - $(STRIP) `echo $(bindir)/sdcppold|sed '$(transform)'` - -# Deleting all the installed files -# -------------------------------- -uninstall: - rm -f $(bindir)/sdcppold - - -# Performing self-test -# -------------------- -check: - - -# Performing installation test -# ---------------------------- -installcheck: - - -# Creating installation directories -# --------------------------------- -installdirs: - $(INSTALL) -d $(bindir) - - -# Creating dependencies -# --------------------- -dep: Makefile.dep - -Makefile.dep: $(SOURCES) *.h $(PRJDIR)/*.h - $(CPP) $(CPPFLAGS) $(M_OR_MM) $(SOURCES) >Makefile.dep - -include Makefile.dep -include clean.mk - -# My rules -# -------- -.c.o: - $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< - -$(SLIBOBJS):%.o:$(SLIB)/%.c - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ - -# Remaking configuration -# ---------------------- -checkconf: - @if [ -f $(PRJDIR)/devel ]; then\ - $(MAKE) -f conf.mk srcdir="$(srcdir)" PRJDIR="$(PRJDIR)" freshconf;\ - fi - -# End of cpp/Makefile diff --git a/support/cpp/Makefile.org b/support/cpp/Makefile.org deleted file mode 100644 index 5779248f..00000000 --- a/support/cpp/Makefile.org +++ /dev/null @@ -1,14 +0,0 @@ - - -YACC=bison -CC=gcc -LEX=flex -TARGETS=$(SDCCDIR)/bin/sdcpp -STD_INC=$(SDCCDIR)/sdcc51inc -CFLAGS=-I . -DSTANDARD_INCLUDE_DIR='"$(STD_INC)"' -O2 -ALLOBJECTS=cppalloc.o cpperror.o cppexp.o cpphash.o cpplib.o cppmain.o -all: $(TARGETS) - -${TARGETS}: ${ALLOBJECTS} - ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${ALLOBJECTS} - diff --git a/support/cpp/clean.mk b/support/cpp/clean.mk deleted file mode 100644 index 14ea6bd6..00000000 --- a/support/cpp/clean.mk +++ /dev/null @@ -1,26 +0,0 @@ -PRJDIR = ../.. - -# Deleting all files created by building the program -# -------------------------------------------------- -clean: - rm -f *core *[%~] *.[oa] - rm -f .[a-z]*~ - rm -f $(PRJDIR)/bin/sdcpp - - -# Deleting all files created by configuring or building the program -# ----------------------------------------------------------------- -distclean: clean - rm -f config.cache config.log config.status - rm -f Makefile *.dep - - -# Like clean but some files may still exist -# ----------------------------------------- -mostlyclean: clean - - -# Deleting everything that can reconstructed by this Makefile. It deletes -# everything deleted by distclean plus files created by bison, etc. -# ----------------------------------------------------------------------- -realclean: distclean diff --git a/support/cpp/conf.mk b/support/cpp/conf.mk deleted file mode 100644 index 879e9bc8..00000000 --- a/support/cpp/conf.mk +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile targets to remake configuration -# - -freshconf: Makefile - -Makefile: $(srcdir)/Makefile.in $(PRJDIR)/configure.in - cd $(PRJDIR) && $(SHELL) ./config.status - -# End of conf.mk diff --git a/support/cpp/config.h b/support/cpp/config.h deleted file mode 100644 index 46d7d467..00000000 --- a/support/cpp/config.h +++ /dev/null @@ -1,30 +0,0 @@ -#if defined(_MSC_VER) - -#include -#include "i386/i386.h" -#include "i386/xm-i386.h" -#define alloca(x) Safe_calloc(1,(x)) -#define bcopy(s, d, n) memcpy(d, s, n) -#define bcmp memcmp -#define bzero(p, l) memset(p, 0, l) -#define index strchr -#define rindex strrchr - -#else - -#include "i386/i386.h" -#include "i386/xm-linux.h" - -#define alloca(x) Safe_calloc(1,(x)) - -#ifdef __BORLANDC__ -#include -#include -#define bcopy(s, d, n) memcpy(d, s, n) -#define bcmp memcmp -#define bzero(p, l) memset(p, 0, l) -#define index strchr -#define rindex strrchr -#endif - -#endif // _MSC_VER diff --git a/support/cpp/cpp.1 b/support/cpp/cpp.1 deleted file mode 100644 index 54c4dfb1..00000000 --- a/support/cpp/cpp.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/cccp.1 diff --git a/support/cpp/cpp.aux b/support/cpp/cpp.aux deleted file mode 100644 index be541303..00000000 --- a/support/cpp/cpp.aux +++ /dev/null @@ -1,132 +0,0 @@ -'xrdef {Top-title}{The C Preprocessor} -'xrdef {Top-pg}{1} -'xrdef {Top-snt}{Chapter'tie1} -'xrdef {Global Actions-title}{Transformations Made Globally} -'xrdef {Global Actions-pg}{1} -'xrdef {Global Actions-snt}{Section'tie1.1} -'xrdef {Commands-title}{Preprocessor Commands} -'xrdef {Commands-pg}{3} -'xrdef {Commands-snt}{Section'tie1.2} -'xrdef {Header Files-title}{Header Files} -'xrdef {Header Files-pg}{3} -'xrdef {Header Files-snt}{Section'tie1.3} -'xrdef {Header Uses-title}{Uses of Header Files} -'xrdef {Header Uses-pg}{4} -'xrdef {Header Uses-snt}{Section'tie1.3.1} -'xrdef {Include Syntax-title}{The \samp {#include} Command} -'xrdef {Include Syntax-pg}{4} -'xrdef {Include Syntax-snt}{Section'tie1.3.2} -'xrdef {Include Operation-title}{How \samp {#include} Works} -'xrdef {Include Operation-pg}{5} -'xrdef {Include Operation-snt}{Section'tie1.3.3} -'xrdef {Once-Only-title}{Once-Only Include Files} -'xrdef {Once-Only-pg}{6} -'xrdef {Once-Only-snt}{Section'tie1.3.4} -'xrdef {Inheritance-title}{Inheritance and Header Files} -'xrdef {Inheritance-pg}{8} -'xrdef {Inheritance-snt}{Section'tie1.3.5} -'xrdef {Macros-title}{Macros} -'xrdef {Macros-pg}{9} -'xrdef {Macros-snt}{Section'tie1.4} -'xrdef {Simple Macros-title}{Simple Macros} -'xrdef {Simple Macros-pg}{9} -'xrdef {Simple Macros-snt}{Section'tie1.4.1} -'xrdef {Argument Macros-title}{Macros with Arguments} -'xrdef {Argument Macros-pg}{10} -'xrdef {Argument Macros-snt}{Section'tie1.4.2} -'xrdef {Predefined-title}{Predefined Macros} -'xrdef {Predefined-pg}{13} -'xrdef {Predefined-snt}{Section'tie1.4.3} -'xrdef {Standard Predefined-title}{Standard Predefined Macros} -'xrdef {Standard Predefined-pg}{13} -'xrdef {Standard Predefined-snt}{Section'tie1.4.3.1} -'xrdef {Nonstandard Predefined-title}{Nonstandard Predefined Macros} -'xrdef {Nonstandard Predefined-pg}{15} -'xrdef {Nonstandard Predefined-snt}{Section'tie1.4.3.2} -'xrdef {Stringification-title}{Stringification} -'xrdef {Stringification-pg}{17} -'xrdef {Stringification-snt}{Section'tie1.4.4} -'xrdef {Concatenation-title}{Concatenation} -'xrdef {Concatenation-pg}{18} -'xrdef {Concatenation-snt}{Section'tie1.4.5} -'xrdef {Undefining-title}{Undefining Macros} -'xrdef {Undefining-pg}{20} -'xrdef {Undefining-snt}{Section'tie1.4.6} -'xrdef {Redefining-title}{Redefining Macros} -'xrdef {Redefining-pg}{20} -'xrdef {Redefining-snt}{Section'tie1.4.7} -'xrdef {Macro Pitfalls-title}{Pitfalls and Subtleties of Macros} -'xrdef {Macro Pitfalls-pg}{21} -'xrdef {Macro Pitfalls-snt}{Section'tie1.4.8} -'xrdef {Misnesting-title}{Improperly Nested Constructs} -'xrdef {Misnesting-pg}{21} -'xrdef {Misnesting-snt}{Section'tie1.4.8.1} -'xrdef {Macro Parentheses-title}{Unintended Grouping of Arithmetic} -'xrdef {Macro Parentheses-pg}{22} -'xrdef {Macro Parentheses-snt}{Section'tie1.4.8.2} -'xrdef {Swallow Semicolon-title}{Swallowing the Semicolon} -'xrdef {Swallow Semicolon-pg}{23} -'xrdef {Swallow Semicolon-snt}{Section'tie1.4.8.3} -'xrdef {Side Effects-title}{Duplication of Side Effects} -'xrdef {Side Effects-pg}{24} -'xrdef {Side Effects-snt}{Section'tie1.4.8.4} -'xrdef {Self-Reference-title}{Self-Referential Macros} -'xrdef {Self-Reference-pg}{25} -'xrdef {Self-Reference-snt}{Section'tie1.4.8.5} -'xrdef {Argument Prescan-title}{Separate Expansion of Macro Arguments} -'xrdef {Argument Prescan-pg}{26} -'xrdef {Argument Prescan-snt}{Section'tie1.4.8.6} -'xrdef {Cascaded Macros-title}{Cascaded Use of Macros} -'xrdef {Cascaded Macros-pg}{29} -'xrdef {Cascaded Macros-snt}{Section'tie1.4.8.7} -'xrdef {Newlines in Args-title}{Newlines in Macro Arguments} -'xrdef {Newlines in Args-pg}{30} -'xrdef {Newlines in Args-snt}{Section'tie1.4.9} -'xrdef {Conditionals-title}{Conditionals} -'xrdef {Conditionals-pg}{30} -'xrdef {Conditionals-snt}{Section'tie1.5} -'xrdef {Conditional Uses-title}{Why Conditionals are Used} -'xrdef {Conditional Uses-pg}{31} -'xrdef {Conditional Uses-snt}{Section'tie1.5.1} -'xrdef {Conditional Syntax-title}{Syntax of Conditionals} -'xrdef {Conditional Syntax-pg}{31} -'xrdef {Conditional Syntax-snt}{Section'tie1.5.2} -'xrdef {#if Command-title}{The \samp {#if} Command} -'xrdef {#if Command-pg}{31} -'xrdef {#if Command-snt}{Section'tie1.5.2.1} -'xrdef {#else Command-title}{The \samp {#else} Command} -'xrdef {#else Command-pg}{32} -'xrdef {#else Command-snt}{Section'tie1.5.2.2} -'xrdef {#elif Command-title}{The \samp {#elif} Command} -'xrdef {#elif Command-pg}{33} -'xrdef {#elif Command-snt}{Section'tie1.5.2.3} -'xrdef {Deleted Code-title}{Keeping Deleted Code for Future Reference} -'xrdef {Deleted Code-pg}{34} -'xrdef {Deleted Code-snt}{Section'tie1.5.3} -'xrdef {Conditionals-Macros-title}{Conditionals and Macros} -'xrdef {Conditionals-Macros-pg}{34} -'xrdef {Conditionals-Macros-snt}{Section'tie1.5.4} -'xrdef {Assertions-title}{Assertions} -'xrdef {Assertions-pg}{36} -'xrdef {Assertions-snt}{Section'tie1.5.5} -'xrdef {#error Command-title}{The \samp {#error} and \samp {#warning} Commands} -'xrdef {#error Command-pg}{38} -'xrdef {#error Command-snt}{Section'tie1.5.6} -'xrdef {Combining Sources-title}{Combining Source Files} -'xrdef {Combining Sources-pg}{39} -'xrdef {Combining Sources-snt}{Section'tie1.6} -'xrdef {Other Commands-title}{Miscellaneous Preprocessor Commands} -'xrdef {Other Commands-pg}{40} -'xrdef {Other Commands-snt}{Section'tie1.7} -'xrdef {Output-title}{C Preprocessor Output} -'xrdef {Output-pg}{41} -'xrdef {Output-snt}{Section'tie1.8} -'xrdef {Invocation-title}{Invoking the C Preprocessor} -'xrdef {Invocation-pg}{41} -'xrdef {Invocation-snt}{Section'tie1.9} -'xrdef {Concept Index-title}{Concept Index} -'xrdef {Concept Index-pg}{47} -'xrdef {Concept Index-snt}{} -'xrdef {Index-title}{Index of Commands, Macros and Options} -'xrdef {Index-pg}{49} -'xrdef {Index-snt}{} diff --git a/support/cpp/cpp.cps b/support/cpp/cpp.cps deleted file mode 100644 index 63ca498f..00000000 --- a/support/cpp/cpp.cps +++ /dev/null @@ -1,66 +0,0 @@ -\initial {#} -\entry {\samp {##}}{18} -\initial {A} -\entry {arguments in macro definitions}{10} -\entry {assertions}{36} -\entry {assertions, undoing}{37} -\initial {B} -\entry {blank macro arguments}{12} -\initial {C} -\entry {cascaded macros}{29} -\entry {commands}{3} -\entry {commenting out code}{34} -\entry {computed \samp {#include}}{5} -\entry {concatenation}{18} -\entry {conditionals}{30} -\initial {E} -\entry {expansion of arguments}{26} -\initial {F} -\entry {function-like macro}{10} -\initial {H} -\entry {header file}{3} -\initial {I} -\entry {including just once}{6} -\entry {inheritance}{8} -\entry {invocation of the preprocessor}{41} -\initial {L} -\entry {line control}{39} -\initial {M} -\entry {macro argument expansion}{26} -\entry {macro body uses macro}{29} -\entry {macros with argument}{10} -\entry {manifest constant}{9} -\initial {N} -\entry {newlines in macro arguments}{30} -\entry {null command}{40} -\initial {O} -\entry {options}{41} -\entry {output format}{41} -\entry {overriding a header file}{8} -\initial {P} -\entry {parentheses in macro bodies}{22} -\entry {pitfalls of macros}{21} -\entry {predefined macros}{13} -\entry {predicates}{36} -\entry {preprocessor commands}{3} -\entry {prescan of macro arguments}{26} -\entry {problems with macros}{21} -\initial {R} -\entry {redefining macros}{20} -\entry {repeated inclusion}{6} -\entry {retracting assertions}{37} -\initial {S} -\entry {second include path}{45} -\entry {self-reference}{25} -\entry {semicolons (after macro calls)}{23} -\entry {side effects (in macro arguments)}{24} -\entry {simple macro}{9} -\entry {space as macro argument}{12} -\entry {standard predefined macros}{13} -\entry {stringification}{17} -\initial {T} -\entry {testing predicates}{36} -\initial {U} -\entry {unassert}{37} -\entry {undefining macros}{20} -\entry {unsafe macros}{24} diff --git a/support/cpp/cpp.fns b/support/cpp/cpp.fns deleted file mode 100644 index 849b4b26..00000000 --- a/support/cpp/cpp.fns +++ /dev/null @@ -1,94 +0,0 @@ -\initial {#} -\entry {\code {#assert}}{37} -\entry {\code {#cpu}}{36} -\entry {\code {#define}}{10} -\entry {\code {#elif}}{33} -\entry {\code {#else}}{32} -\entry {\code {#error}}{38} -\entry {\code {#ident}}{40} -\entry {\code {#if}}{31} -\entry {\code {#ifdef}}{35} -\entry {\code {#ifndef}}{35} -\entry {\code {#import}}{7} -\entry {\code {#include}}{4} -\entry {\code {#include{\_}next}}{8} -\entry {\code {#line}}{39} -\entry {\code {#machine}}{36} -\entry {\code {#pragma}}{40} -\entry {\code {#pragma once}}{7} -\entry {\code {#system}}{36} -\entry {\code {#unassert}}{37} -\entry {\code {#warning}}{38} -\initial {-} -\entry {\code {-$}}{46} -\entry {\code {-A}}{44} -\entry {\code {-C}}{42} -\entry {\code {-D}}{43} -\entry {\code {-dD}}{44} -\entry {\code {-dM}}{44} -\entry {\code {-H}}{45} -\entry {\code {-I}}{43} -\entry {\code {-idirafter}}{45} -\entry {\code {-imacros}}{45} -\entry {\code {-include}}{45} -\entry {\code {-iprefix}}{45} -\entry {\code {-isystem}}{45} -\entry {\code {-iwithprefix}}{45} -\entry {\code {-lang-c}}{45} -\entry {\code {-lang-c{\tt\char43}{\tt\char43}}}{45} -\entry {\code {-lang-objc}}{45} -\entry {\code {-lang-objc{\tt\char43}{\tt\char43}}}{45} -\entry {\code {-M}}{44} -\entry {\code {-MD}}{44} -\entry {\code {-MM}}{44} -\entry {\code {-MMD}}{45} -\entry {\code {-nostdinc}}{43} -\entry {\code {-nostdinc{\tt\char43}{\tt\char43}}}{43} -\entry {\code {-P}}{42} -\entry {\code {-pedantic}}{43} -\entry {\code {-pedantic-errors}}{43} -\entry {\code {-traditional}}{42} -\entry {\code {-trigraphs}}{42} -\entry {\code {-U}}{44} -\entry {\code {-undef}}{44} -\entry {\code {-Wall}}{43} -\entry {\code {-Wcomment}}{43} -\entry {\code {-Wtraditional}}{43} -\entry {\code {-Wtrigraphs}}{43} -\initial {{\_}} -\entry {\code {{\_}{\_}BASE{\_}FILE{\_}{\_}}}{15} -\entry {\code {{\_}{\_}CHAR{\_}UNSIGNED{\_}{\_}}}{15} -\entry {\code {{\_}{\_}cplusplus}}{14} -\entry {\code {{\_}{\_}DATE{\_}{\_}}}{14} -\entry {\code {{\_}{\_}FILE{\_}{\_}}}{13} -\entry {\code {{\_}{\_}GNUC{\_}{\_}}}{14} -\entry {\code {{\_}{\_}GNUG{\_}{\_}}}{14} -\entry {\code {{\_}{\_}INCLUDE{\_}LEVEL{\_}}}{14} -\entry {\code {{\_}{\_}LINE{\_}{\_}}}{13} -\entry {\code {{\_}{\_}OPTIMIZE{\_}{\_}}}{15} -\entry {\code {{\_}{\_}STDC{\_}{\_}}}{14} -\entry {\code {{\_}{\_}STRICT{\_}ANSI{\_}{\_}}}{15} -\entry {\code {{\_}{\_}TIME{\_}{\_}}}{14} -\entry {\code {{\_}{\_}VERSION{\_}{\_}}}{15} -\entry {\code {{\_}AM29000}}{16} -\entry {\code {{\_}AM29K}}{16} -\initial {B} -\entry {\code {BSD}}{16} -\initial {D} -\entry {\code {defined}}{34} -\initial {M} -\entry {\code {M68020}}{16} -\entry {\code {m68k}}{16} -\entry {\code {mc68000}}{16} -\initial {N} -\entry {\code {ns32000}}{16} -\initial {P} -\entry {\code {pyr}}{16} -\initial {S} -\entry {\code {sequent}}{16} -\entry {\code {sun}}{16} -\entry {\code {system header files}}{4} -\initial {U} -\entry {\code {unix}}{16} -\initial {V} -\entry {\code {vax}}{16} diff --git a/support/cpp/cpp.info b/support/cpp/cpp.info deleted file mode 100644 index 7ab558bd..00000000 --- a/support/cpp/cpp.info +++ /dev/null @@ -1,75 +0,0 @@ -This is Info file cpp.info, produced by Makeinfo version 1.67 from the -input file cpp.texi. - - This file documents the GNU C Preprocessor. - - Copyright 1987, 1989, 1991, 1992, 1993, 1994, 1995 Free Software -Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided also -that the entire resulting derived work is distributed under the terms -of a permission notice identical to this one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions. - - -Indirect: -cpp.info-1: 798 -cpp.info-2: 50204 -cpp.info-3: 90189 - -Tag Table: -(Indirect) -Node: Top798 -Node: Global Actions3370 -Node: Directives5890 -Node: Header Files7577 -Node: Header Uses8236 -Node: Include Syntax9728 -Node: Include Operation12870 -Node: Once-Only14732 -Node: Inheritance17157 -Node: Macros19719 -Node: Simple Macros20633 -Node: Argument Macros23621 -Node: Predefined29419 -Node: Standard Predefined29849 -Node: Nonstandard Predefined36986 -Node: Stringification40562 -Node: Concatenation43488 -Node: Undefining46761 -Node: Redefining47800 -Node: Macro Pitfalls49100 -Node: Misnesting50204 -Node: Macro Parentheses51218 -Node: Swallow Semicolon53095 -Node: Side Effects54995 -Node: Self-Reference56693 -Node: Argument Prescan58969 -Node: Cascaded Macros63971 -Node: Newlines in Args65116 -Node: Conditionals66461 -Node: Conditional Uses67813 -Node: Conditional Syntax69236 -Node: #if Directive69822 -Node: #else Directive72111 -Node: #elif Directive72778 -Node: Deleted Code74156 -Node: Conditionals-Macros75217 -Node: Assertions78902 -Node: #error Directive83137 -Node: Combining Sources84577 -Node: Other Directives87488 -Node: Output88950 -Node: Invocation90189 -Node: Concept Index102013 -Node: Index104866 - -End Tag Table diff --git a/support/cpp/cpp.info-1 b/support/cpp/cpp.info-1 deleted file mode 100644 index d7694a77..00000000 --- a/support/cpp/cpp.info-1 +++ /dev/null @@ -1,1189 +0,0 @@ -This is Info file cpp.info, produced by Makeinfo version 1.67 from the -input file cpp.texi. - - This file documents the GNU C Preprocessor. - - Copyright 1987, 1989, 1991, 1992, 1993, 1994, 1995 Free Software -Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided also -that the entire resulting derived work is distributed under the terms -of a permission notice identical to this one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions. - - -File: cpp.info, Node: Top, Next: Global Actions, Up: (DIR) - -The C Preprocessor -****************** - - The C preprocessor is a "macro processor" that is used automatically -by the C compiler to transform your program before actual compilation. -It is called a macro processor because it allows you to define "macros", -which are brief abbreviations for longer constructs. - - The C preprocessor provides four separate facilities that you can -use as you see fit: - - * Inclusion of header files. These are files of declarations that - can be substituted into your program. - - * Macro expansion. You can define "macros", which are abbreviations - for arbitrary fragments of C code, and then the C preprocessor will - replace the macros with their definitions throughout the program. - - * Conditional compilation. Using special preprocessing directives, - you can include or exclude parts of the program according to - various conditions. - - * Line control. If you use a program to combine or rearrange source - files into an intermediate file which is then compiled, you can - use line control to inform the compiler of where each source line - originally came from. - - C preprocessors vary in some details. This manual discusses the GNU -C preprocessor, the C Compatible Compiler Preprocessor. The GNU C -preprocessor provides a superset of the features of ANSI Standard C. - - ANSI Standard C requires the rejection of many harmless constructs -commonly used by today's C programs. Such incompatibility would be -inconvenient for users, so the GNU C preprocessor is configured to -accept these constructs by default. Strictly speaking, to get ANSI -Standard C, you must use the options `-trigraphs', `-undef' and -`-pedantic', but in practice the consequences of having strict ANSI -Standard C make it undesirable to do this. *Note Invocation::. - -* Menu: - -* Global Actions:: Actions made uniformly on all input files. -* Directives:: General syntax of preprocessing directives. -* Header Files:: How and why to use header files. -* Macros:: How and why to use macros. -* Conditionals:: How and why to use conditionals. -* Combining Sources:: Use of line control when you combine source files. -* Other Directives:: Miscellaneous preprocessing directives. -* Output:: Format of output from the C preprocessor. -* Invocation:: How to invoke the preprocessor; command options. -* Concept Index:: Index of concepts and terms. -* Index:: Index of directives, predefined macros and options. - - -File: cpp.info, Node: Global Actions, Next: Directives, Prev: Top, Up: Top - -Transformations Made Globally -============================= - - Most C preprocessor features are inactive unless you give specific -directives to request their use. (Preprocessing directives are lines -starting with `#'; *note Directives::.). But there are three -transformations that the preprocessor always makes on all the input it -receives, even in the absence of directives. - - * All C comments are replaced with single spaces. - - * Backslash-Newline sequences are deleted, no matter where. This - feature allows you to break long lines for cosmetic purposes - without changing their meaning. - - * Predefined macro names are replaced with their expansions (*note - Predefined::.). - - The first two transformations are done *before* nearly all other -parsing and before preprocessing directives are recognized. Thus, for -example, you can split a line cosmetically with Backslash-Newline -anywhere (except when trigraphs are in use; see below). - - /* - */ # /* - */ defi\ - ne FO\ - O 10\ - 20 - -is equivalent into `#define FOO 1020'. You can split even an escape -sequence with Backslash-Newline. For example, you can split `"foo\bar"' -between the `\' and the `b' to get - - "foo\\ - bar" - -This behavior is unclean: in all other contexts, a Backslash can be -inserted in a string constant as an ordinary character by writing a -double Backslash, and this creates an exception. But the ANSI C -standard requires it. (Strict ANSI C does not allow Newlines in string -constants, so they do not consider this a problem.) - - But there are a few exceptions to all three transformations. - - * C comments and predefined macro names are not recognized inside a - `#include' directive in which the file name is delimited with `<' - and `>'. - - * C comments and predefined macro names are never recognized within a - character or string constant. (Strictly speaking, this is the - rule, not an exception, but it is worth noting here anyway.) - - * Backslash-Newline may not safely be used within an ANSI "trigraph". - Trigraphs are converted before Backslash-Newline is deleted. If - you write what looks like a trigraph with a Backslash-Newline - inside, the Backslash-Newline is deleted as usual, but it is then - too late to recognize the trigraph. - - This exception is relevant only if you use the `-trigraphs' option - to enable trigraph processing. *Note Invocation::. - - -File: cpp.info, Node: Directives, Next: Header Files, Prev: Global Actions, Up: Top - -Preprocessing Directives -======================== - - Most preprocessor features are active only if you use preprocessing -directives to request their use. - - Preprocessing directives are lines in your program that start with -`#'. The `#' is followed by an identifier that is the "directive name". -For example, `#define' is the directive that defines a macro. -Whitespace is also allowed before and after the `#'. - - The set of valid directive names is fixed. Programs cannot define -new preprocessing directives. - - Some directive names require arguments; these make up the rest of -the directive line and must be separated from the directive name by -whitespace. For example, `#define' must be followed by a macro name -and the intended expansion of the macro. *Note Simple Macros::. - - A preprocessing directive cannot be more than one line in normal -circumstances. It may be split cosmetically with Backslash-Newline, -but that has no effect on its meaning. Comments containing Newlines -can also divide the directive into multiple lines, but the comments are -changed to Spaces before the directive is interpreted. The only way a -significant Newline can occur in a preprocessing directive is within a -string constant or character constant. Note that most C compilers that -might be applied to the output from the preprocessor do not accept -string or character constants containing Newlines. - - The `#' and the directive name cannot come from a macro expansion. -For example, if `foo' is defined as a macro expanding to `define', that -does not make `#foo' a valid preprocessing directive. - - -File: cpp.info, Node: Header Files, Next: Macros, Prev: Directives, Up: Top - -Header Files -============ - - A header file is a file containing C declarations and macro -definitions (*note Macros::.) to be shared between several source -files. You request the use of a header file in your program with the C -preprocessing directive `#include'. - -* Menu: - -* Header Uses:: What header files are used for. -* Include Syntax:: How to write `#include' directives. -* Include Operation:: What `#include' does. -* Once-Only:: Preventing multiple inclusion of one header file. -* Inheritance:: Including one header file in another header file. - - -File: cpp.info, Node: Header Uses, Next: Include Syntax, Prev: Header Files, Up: Header Files - -Uses of Header Files --------------------- - - Header files serve two kinds of purposes. - - * System header files declare the interfaces to parts of the - operating system. You include them in your program to supply the - definitions and declarations you need to invoke system calls and - libraries. - - * Your own header files contain declarations for interfaces between - the source files of your program. Each time you have a group of - related declarations and macro definitions all or most of which - are needed in several different source files, it is a good idea to - create a header file for them. - - Including a header file produces the same results in C compilation as -copying the header file into each source file that needs it. But such -copying would be time-consuming and error-prone. With a header file, -the related declarations appear in only one place. If they need to be -changed, they can be changed in one place, and programs that include -the header file will automatically use the new version when next -recompiled. The header file eliminates the labor of finding and -changing all the copies as well as the risk that a failure to find one -copy will result in inconsistencies within a program. - - The usual convention is to give header files names that end with -`.h'. Avoid unusual characters in header file names, as they reduce -portability. - - -File: cpp.info, Node: Include Syntax, Next: Include Operation, Prev: Header Uses, Up: Header Files - -The `#include' Directive ------------------------- - - Both user and system header files are included using the -preprocessing directive `#include'. It has three variants: - -`#include ' - This variant is used for system header files. It searches for a - file named FILE in a list of directories specified by you, then in - a standard list of system directories. You specify directories to - search for header files with the command option `-I' (*note - Invocation::.). The option `-nostdinc' inhibits searching the - standard system directories; in this case only the directories you - specify are searched. - - The parsing of this form of `#include' is slightly special because - comments are not recognized within the `<...>'. Thus, in - `#include ' the `/*' does not start a comment and the - directive specifies inclusion of a system header file named - `x/*y'. Of course, a header file with such a name is unlikely to - exist on Unix, where shell wildcard features would make it hard to - manipulate. - - The argument FILE may not contain a `>' character. It may, - however, contain a `<' character. - -`#include "FILE"' - This variant is used for header files of your own program. It - searches for a file named FILE first in the current directory, - then in the same directories used for system header files. The - current directory is the directory of the current input file. It - is tried first because it is presumed to be the location of the - files that the current input file refers to. (If the `-I-' option - is used, the special treatment of the current directory is - inhibited.) - - The argument FILE may not contain `"' characters. If backslashes - occur within FILE, they are considered ordinary text characters, - not escape characters. None of the character escape sequences - appropriate to string constants in C are processed. Thus, - `#include "x\n\\y"' specifies a filename containing three - backslashes. It is not clear why this behavior is ever useful, but - the ANSI standard specifies it. - -`#include ANYTHING ELSE' - This variant is called a "computed #include". Any `#include' - directive whose argument does not fit the above two forms is a - computed include. The text ANYTHING ELSE is checked for macro - calls, which are expanded (*note Macros::.). When this is done, - the result must fit one of the above two variants--in particular, - the expanded text must in the end be surrounded by either quotes - or angle braces. - - This feature allows you to define a macro which controls the file - name to be used at a later point in the program. One application - of this is to allow a site-specific configuration file for your - program to specify the names of the system include files to be - used. This can help in porting the program to various operating - systems in which the necessary system header files are found in - different places. - - -File: cpp.info, Node: Include Operation, Next: Once-Only, Prev: Include Syntax, Up: Header Files - -How `#include' Works --------------------- - - The `#include' directive works by directing the C preprocessor to -scan the specified file as input before continuing with the rest of the -current file. The output from the preprocessor contains the output -already generated, followed by the output resulting from the included -file, followed by the output that comes from the text after the -`#include' directive. For example, given a header file `header.h' as -follows, - - char *test (); - -and a main program called `program.c' that uses the header file, like -this, - - int x; - #include "header.h" - - main () - { - printf (test ()); - } - -the output generated by the C preprocessor for `program.c' as input -would be - - int x; - char *test (); - - main () - { - printf (test ()); - } - - Included files are not limited to declarations and macro -definitions; those are merely the typical uses. Any fragment of a C -program can be included from another file. The include file could even -contain the beginning of a statement that is concluded in the -containing file, or the end of a statement that was started in the -including file. However, a comment or a string or character constant -may not start in the included file and finish in the including file. -An unterminated comment, string constant or character constant in an -included file is considered to end (with an error message) at the end -of the file. - - It is possible for a header file to begin or end a syntactic unit -such as a function definition, but that would be very confusing, so -don't do it. - - The line following the `#include' directive is always treated as a -separate line by the C preprocessor even if the included file lacks a -final newline. - - -File: cpp.info, Node: Once-Only, Next: Inheritance, Prev: Include Operation, Up: Header Files - -Once-Only Include Files ------------------------ - - Very often, one header file includes another. It can easily result -that a certain header file is included more than once. This may lead -to errors, if the header file defines structure types or typedefs, and -is certainly wasteful. Therefore, we often wish to prevent multiple -inclusion of a header file. - - The standard way to do this is to enclose the entire real contents -of the file in a conditional, like this: - - #ifndef FILE_FOO_SEEN - #define FILE_FOO_SEEN - - THE ENTIRE FILE - - #endif /* FILE_FOO_SEEN */ - - The macro `FILE_FOO_SEEN' indicates that the file has been included -once already. In a user header file, the macro name should not begin -with `_'. In a system header file, this name should begin with `__' to -avoid conflicts with user programs. In any kind of header file, the -macro name should contain the name of the file and some additional -text, to avoid conflicts with other header files. - - The GNU C preprocessor is programmed to notice when a header file -uses this particular construct and handle it efficiently. If a header -file is contained entirely in a `#ifndef' conditional, then it records -that fact. If a subsequent `#include' specifies the same file, and the -macro in the `#ifndef' is already defined, then the file is entirely -skipped, without even reading it. - - There is also an explicit directive to tell the preprocessor that it -need not include a file more than once. This is called `#pragma once', -and was used *in addition to* the `#ifndef' conditional around the -contents of the header file. `#pragma once' is now obsolete and should -not be used at all. - - In the Objective C language, there is a variant of `#include' called -`#import' which includes a file, but does so at most once. If you use -`#import' *instead of* `#include', then you don't need the conditionals -inside the header file to prevent multiple execution of the contents. - - `#import' is obsolete because it is not a well designed feature. It -requires the users of a header file--the applications programmers--to -know that a certain header file should only be included once. It is -much better for the header file's implementor to write the file so that -users don't need to know this. Using `#ifndef' accomplishes this goal. - - -File: cpp.info, Node: Inheritance, Prev: Once-Only, Up: Header Files - -Inheritance and Header Files ----------------------------- - - "Inheritance" is what happens when one object or file derives some -of its contents by virtual copying from another object or file. In the -case of C header files, inheritance means that one header file includes -another header file and then replaces or adds something. - - If the inheriting header file and the base header file have different -names, then inheritance is straightforward: simply write `#include -"BASE"' in the inheriting file. - - Sometimes it is necessary to give the inheriting file the same name -as the base file. This is less straightforward. - - For example, suppose an application program uses the system header -file `sys/signal.h', but the version of `/usr/include/sys/signal.h' on -a particular system doesn't do what the application program expects. -It might be convenient to define a "local" version, perhaps under the -name `/usr/local/include/sys/signal.h', to override or add to the one -supplied by the system. - - You can do this by using the option `-I.' for compilation, and -writing a file `sys/signal.h' that does what the application program -expects. But making this file include the standard `sys/signal.h' is -not so easy--writing `#include ' in that file doesn't -work, because it includes your own version of the file, not the -standard system version. Used in that file itself, this leads to an -infinite recursion and a fatal error in compilation. - - `#include ' would find the proper file, -but that is not clean, since it makes an assumption about where the -system header file is found. This is bad for maintenance, since it -means that any change in where the system's header files are kept -requires a change somewhere else. - - The clean way to solve this problem is to use `#include_next', which -means, "Include the *next* file with this name." This directive works -like `#include' except in searching for the specified file: it starts -searching the list of header file directories *after* the directory in -which the current file was found. - - Suppose you specify `-I /usr/local/include', and the list of -directories to search also includes `/usr/include'; and suppose that -both directories contain a file named `sys/signal.h'. Ordinary -`#include ' finds the file under `/usr/local/include'. -If that file contains `#include_next ', it starts -searching after that directory, and finds the file in `/usr/include'. - - -File: cpp.info, Node: Macros, Next: Conditionals, Prev: Header Files, Up: Top - -Macros -====== - - A macro is a sort of abbreviation which you can define once and then -use later. There are many complicated features associated with macros -in the C preprocessor. - -* Menu: - -* Simple Macros:: Macros that always expand the same way. -* Argument Macros:: Macros that accept arguments that are substituted - into the macro expansion. -* Predefined:: Predefined macros that are always available. -* Stringification:: Macro arguments converted into string constants. -* Concatenation:: Building tokens from parts taken from macro arguments. -* Undefining:: Cancelling a macro's definition. -* Redefining:: Changing a macro's definition. -* Macro Pitfalls:: Macros can confuse the unwary. Here we explain - several common problems and strange features. - - -File: cpp.info, Node: Simple Macros, Next: Argument Macros, Prev: Macros, Up: Macros - -Simple Macros -------------- - - A "simple macro" is a kind of abbreviation. It is a name which -stands for a fragment of code. Some people refer to these as "manifest -constants". - - Before you can use a macro, you must "define" it explicitly with the -`#define' directive. `#define' is followed by the name of the macro -and then the code it should be an abbreviation for. For example, - - #define BUFFER_SIZE 1020 - -defines a macro named `BUFFER_SIZE' as an abbreviation for the text -`1020'. If somewhere after this `#define' directive there comes a C -statement of the form - - foo = (char *) xmalloc (BUFFER_SIZE); - -then the C preprocessor will recognize and "expand" the macro -`BUFFER_SIZE', resulting in - - foo = (char *) xmalloc (1020); - - The use of all upper case for macro names is a standard convention. -Programs are easier to read when it is possible to tell at a glance -which names are macros. - - Normally, a macro definition must be a single line, like all C -preprocessing directives. (You can split a long macro definition -cosmetically with Backslash-Newline.) There is one exception: Newlines -can be included in the macro definition if within a string or character -constant. This is because it is not possible for a macro definition to -contain an unbalanced quote character; the definition automatically -extends to include the matching quote character that ends the string or -character constant. Comments within a macro definition may contain -Newlines, which make no difference since the comments are entirely -replaced with Spaces regardless of their contents. - - Aside from the above, there is no restriction on what can go in a -macro body. Parentheses need not balance. The body need not resemble -valid C code. (But if it does not, you may get error messages from the -C compiler when you use the macro.) - - The C preprocessor scans your program sequentially, so macro -definitions take effect at the place you write them. Therefore, the -following input to the C preprocessor - - foo = X; - #define X 4 - bar = X; - -produces as output - - foo = X; - - bar = 4; - - After the preprocessor expands a macro name, the macro's definition -body is appended to the front of the remaining input, and the check for -macro calls continues. Therefore, the macro body can contain calls to -other macros. For example, after - - #define BUFSIZE 1020 - #define TABLESIZE BUFSIZE - -the name `TABLESIZE' when used in the program would go through two -stages of expansion, resulting ultimately in `1020'. - - This is not at all the same as defining `TABLESIZE' to be `1020'. -The `#define' for `TABLESIZE' uses exactly the body you specify--in -this case, `BUFSIZE'--and does not check to see whether it too is the -name of a macro. It's only when you *use* `TABLESIZE' that the result -of its expansion is checked for more macro names. *Note Cascaded -Macros::. - - -File: cpp.info, Node: Argument Macros, Next: Predefined, Prev: Simple Macros, Up: Macros - -Macros with Arguments ---------------------- - - A simple macro always stands for exactly the same text, each time it -is used. Macros can be more flexible when they accept "arguments". -Arguments are fragments of code that you supply each time the macro is -used. These fragments are included in the expansion of the macro -according to the directions in the macro definition. A macro that -accepts arguments is called a "function-like macro" because the syntax -for using it looks like a function call. - - To define a macro that uses arguments, you write a `#define' -directive with a list of "argument names" in parentheses after the name -of the macro. The argument names may be any valid C identifiers, -separated by commas and optionally whitespace. The open-parenthesis -must follow the macro name immediately, with no space in between. - - For example, here is a macro that computes the minimum of two numeric -values, as it is defined in many C programs: - - #define min(X, Y) ((X) < (Y) ? (X) : (Y)) - -(This is not the best way to define a "minimum" macro in GNU C. *Note -Side Effects::, for more information.) - - To use a macro that expects arguments, you write the name of the -macro followed by a list of "actual arguments" in parentheses, -separated by commas. The number of actual arguments you give must -match the number of arguments the macro expects. Examples of use of -the macro `min' include `min (1, 2)' and `min (x + 28, *p)'. - - The expansion text of the macro depends on the arguments you use. -Each of the argument names of the macro is replaced, throughout the -macro definition, with the corresponding actual argument. Using the -same macro `min' defined above, `min (1, 2)' expands into - - ((1) < (2) ? (1) : (2)) - -where `1' has been substituted for `X' and `2' for `Y'. - - Likewise, `min (x + 28, *p)' expands into - - ((x + 28) < (*p) ? (x + 28) : (*p)) - - Parentheses in the actual arguments must balance; a comma within -parentheses does not end an argument. However, there is no requirement -for brackets or braces to balance, and they do not prevent a comma from -separating arguments. Thus, - - macro (array[x = y, x + 1]) - -passes two arguments to `macro': `array[x = y' and `x + 1]'. If you -want to supply `array[x = y, x + 1]' as an argument, you must write it -as `array[(x = y, x + 1)]', which is equivalent C code. - - After the actual arguments are substituted into the macro body, the -entire result is appended to the front of the remaining input, and the -check for macro calls continues. Therefore, the actual arguments can -contain calls to other macros, either with or without arguments, or -even to the same macro. The macro body can also contain calls to other -macros. For example, `min (min (a, b), c)' expands into this text: - - ((((a) < (b) ? (a) : (b))) < (c) - ? (((a) < (b) ? (a) : (b))) - : (c)) - -(Line breaks shown here for clarity would not actually be generated.) - - If a macro `foo' takes one argument, and you want to supply an empty -argument, you must write at least some whitespace between the -parentheses, like this: `foo ( )'. Just `foo ()' is providing no -arguments, which is an error if `foo' expects an argument. But `foo0 -()' is the correct way to call a macro defined to take zero arguments, -like this: - - #define foo0() ... - - If you use the macro name followed by something other than an -open-parenthesis (after ignoring any spaces, tabs and comments that -follow), it is not a call to the macro, and the preprocessor does not -change what you have written. Therefore, it is possible for the same -name to be a variable or function in your program as well as a macro, -and you can choose in each instance whether to refer to the macro (if -an actual argument list follows) or the variable or function (if an -argument list does not follow). - - Such dual use of one name could be confusing and should be avoided -except when the two meanings are effectively synonymous: that is, when -the name is both a macro and a function and the two have similar -effects. You can think of the name simply as a function; use of the -name for purposes other than calling it (such as, to take the address) -will refer to the function, while calls will expand the macro and -generate better but equivalent code. For example, you can use a -function named `min' in the same source file that defines the macro. -If you write `&min' with no argument list, you refer to the function. -If you write `min (x, bb)', with an argument list, the macro is -expanded. If you write `(min) (a, bb)', where the name `min' is not -followed by an open-parenthesis, the macro is not expanded, so you wind -up with a call to the function `min'. - - You may not define the same name as both a simple macro and a macro -with arguments. - - In the definition of a macro with arguments, the list of argument -names must follow the macro name immediately with no space in between. -If there is a space after the macro name, the macro is defined as -taking no arguments, and all the rest of the line is taken to be the -expansion. The reason for this is that it is often useful to define a -macro that takes no arguments and whose definition begins with an -identifier in parentheses. This rule about spaces makes it possible -for you to do either this: - - #define FOO(x) - 1 / (x) - -(which defines `FOO' to take an argument and expand into minus the -reciprocal of that argument) or this: - - #define BAR (x) - 1 / (x) - -(which defines `BAR' to take no argument and always expand into `(x) - -1 / (x)'). - - Note that the *uses* of a macro with arguments can have spaces before -the left parenthesis; it's the *definition* where it matters whether -there is a space. - - -File: cpp.info, Node: Predefined, Next: Stringification, Prev: Argument Macros, Up: Macros - -Predefined Macros ------------------ - - Several simple macros are predefined. You can use them without -giving definitions for them. They fall into two classes: standard -macros and system-specific macros. - -* Menu: - -* Standard Predefined:: Standard predefined macros. -* Nonstandard Predefined:: Nonstandard predefined macros. - - -File: cpp.info, Node: Standard Predefined, Next: Nonstandard Predefined, Prev: Predefined, Up: Predefined - -Standard Predefined Macros -.......................... - - The standard predefined macros are available with the same meanings -regardless of the machine or operating system on which you are using -GNU C. Their names all start and end with double underscores. Those -preceding `__GNUC__' in this table are standardized by ANSI C; the rest -are GNU C extensions. - -`__FILE__' - This macro expands to the name of the current input file, in the - form of a C string constant. The precise name returned is the one - that was specified in `#include' or as the input file name - argument. - -`__LINE__' - This macro expands to the current input line number, in the form - of a decimal integer constant. While we call it a predefined - macro, it's a pretty strange macro, since its "definition" changes - with each new line of source code. - - This and `__FILE__' are useful in generating an error message to - report an inconsistency detected by the program; the message can - state the source line at which the inconsistency was detected. - For example, - - fprintf (stderr, "Internal error: " - "negative string length " - "%d at %s, line %d.", - length, __FILE__, __LINE__); - - A `#include' directive changes the expansions of `__FILE__' and - `__LINE__' to correspond to the included file. At the end of that - file, when processing resumes on the input file that contained the - `#include' directive, the expansions of `__FILE__' and `__LINE__' - revert to the values they had before the `#include' (but - `__LINE__' is then incremented by one as processing moves to the - line after the `#include'). - - The expansions of both `__FILE__' and `__LINE__' are altered if a - `#line' directive is used. *Note Combining Sources::. - -`__DATE__' - This macro expands to a string constant that describes the date on - which the preprocessor is being run. The string constant contains - eleven characters and looks like `"Jan 29 1987"' or `"Apr 1 1905"'. - -`__TIME__' - This macro expands to a string constant that describes the time at - which the preprocessor is being run. The string constant contains - eight characters and looks like `"23:59:01"'. - -`__STDC__' - This macro expands to the constant 1, to signify that this is ANSI - Standard C. (Whether that is actually true depends on what C - compiler will operate on the output from the preprocessor.) - -`__STDC_VERSION__' - This macro expands to the C Standard's version number, a long - integer constant of the form `YYYYMML' where YYYY and MM are the - year and month of the Standard version. This signifies which - version of the C Standard the preprocessor conforms to. Like - `__STDC__', whether this version number is accurate for the entire - implementation depends on what C compiler will operate on the - output from the preprocessor. - -`__GNUC__' - This macro is defined if and only if this is GNU C. This macro is - defined only when the entire GNU C compiler is in use; if you - invoke the preprocessor directly, `__GNUC__' is undefined. The - value identifies the major version number of GNU CC (`1' for GNU CC - version 1, which is now obsolete, and `2' for version 2). - -`__GNUC_MINOR__' - The macro contains the minor version number of the compiler. This - can be used to work around differences between different releases - of the compiler (for example, if gcc 2.6.3 is known to support a - feature, you can test for `__GNUC__ > 2 || (__GNUC__ == 2 && - __GNUC_MINOR__ >= 6)'). The last number, `3' in the example - above, denotes the bugfix level of the compiler; no macro contains - this value. - -`__GNUG__' - The GNU C compiler defines this when the compilation language is - C++; use `__GNUG__' to distinguish between GNU C and GNU C++. - -`__cplusplus' - The draft ANSI standard for C++ used to require predefining this - variable. Though it is no longer required, GNU C++ continues to - define it, as do other popular C++ compilers. You can use - `__cplusplus' to test whether a header is compiled by a C compiler - or a C++ compiler. - -`__STRICT_ANSI__' - This macro is defined if and only if the `-ansi' switch was - specified when GNU C was invoked. Its definition is the null - string. This macro exists primarily to direct certain GNU header - files not to define certain traditional Unix constructs which are - incompatible with ANSI C. - -`__BASE_FILE__' - This macro expands to the name of the main input file, in the form - of a C string constant. This is the source file that was specified - as an argument when the C compiler was invoked. - -`__INCLUDE_LEVEL__' - This macro expands to a decimal integer constant that represents - the depth of nesting in include files. The value of this macro is - incremented on every `#include' directive and decremented at every - end of file. For input files specified by command line arguments, - the nesting level is zero. - -`__VERSION__' - This macro expands to a string which describes the version number - of GNU C. The string is normally a sequence of decimal numbers - separated by periods, such as `"2.6.0"'. The only reasonable use - of this macro is to incorporate it into a string constant. - -`__OPTIMIZE__' - This macro is defined in optimizing compilations. It causes - certain GNU header files to define alternative macro definitions - for some system library functions. It is unwise to refer to or - test the definition of this macro unless you make very sure that - programs will execute with the same effect regardless. - -`__CHAR_UNSIGNED__' - This macro is defined if and only if the data type `char' is - unsigned on the target machine. It exists to cause the standard - header file `limit.h' to work correctly. It is bad practice to - refer to this macro yourself; instead, refer to the standard - macros defined in `limit.h'. The preprocessor uses this macro to - determine whether or not to sign-extend large character constants - written in octal; see *Note The `#if' Directive: #if Directive. - -`__REGISTER_PREFIX__' - This macro expands to a string describing the prefix applied to cpu - registers in assembler code. It can be used to write assembler - code that is usable in multiple environments. For example, in the - `m68k-aout' environment it expands to the string `""', but in the - `m68k-coff' environment it expands to the string `"%"'. - -`__USER_LABEL_PREFIX__' - This macro expands to a string describing the prefix applied to - user generated labels in assembler code. It can be used to write - assembler code that is usable in multiple environments. For - example, in the `m68k-aout' environment it expands to the string - `"_"', but in the `m68k-coff' environment it expands to the string - `""'. - - -File: cpp.info, Node: Nonstandard Predefined, Prev: Standard Predefined, Up: Predefined - -Nonstandard Predefined Macros -............................. - - The C preprocessor normally has several predefined macros that vary -between machines because their purpose is to indicate what type of -system and machine is in use. This manual, being for all systems and -machines, cannot tell you exactly what their names are; instead, we -offer a list of some typical ones. You can use `cpp -dM' to see the -values of predefined macros; see *Note Invocation::. - - Some nonstandard predefined macros describe the operating system in -use, with more or less specificity. For example, - -`unix' - `unix' is normally predefined on all Unix systems. - -`BSD' - `BSD' is predefined on recent versions of Berkeley Unix (perhaps - only in version 4.3). - - Other nonstandard predefined macros describe the kind of CPU, with -more or less specificity. For example, - -`vax' - `vax' is predefined on Vax computers. - -`mc68000' - `mc68000' is predefined on most computers whose CPU is a Motorola - 68000, 68010 or 68020. - -`m68k' - `m68k' is also predefined on most computers whose CPU is a 68000, - 68010 or 68020; however, some makers use `mc68000' and some use - `m68k'. Some predefine both names. What happens in GNU C depends - on the system you are using it on. - -`M68020' - `M68020' has been observed to be predefined on some systems that - use 68020 CPUs--in addition to `mc68000' and `m68k', which are - less specific. - -`_AM29K' -`_AM29000' - Both `_AM29K' and `_AM29000' are predefined for the AMD 29000 CPU - family. - -`ns32000' - `ns32000' is predefined on computers which use the National - Semiconductor 32000 series CPU. - - Yet other nonstandard predefined macros describe the manufacturer of -the system. For example, - -`sun' - `sun' is predefined on all models of Sun computers. - -`pyr' - `pyr' is predefined on all models of Pyramid computers. - -`sequent' - `sequent' is predefined on all models of Sequent computers. - - These predefined symbols are not only nonstandard, they are contrary -to the ANSI standard because their names do not start with underscores. -Therefore, the option `-ansi' inhibits the definition of these symbols. - - This tends to make `-ansi' useless, since many programs depend on the -customary nonstandard predefined symbols. Even system header files -check them and will generate incorrect declarations if they do not find -the names that are expected. You might think that the header files -supplied for the Uglix computer would not need to test what machine -they are running on, because they can simply assume it is the Uglix; -but often they do, and they do so using the customary names. As a -result, very few C programs will compile with `-ansi'. We intend to -avoid such problems on the GNU system. - - What, then, should you do in an ANSI C program to test the type of -machine it will run on? - - GNU C offers a parallel series of symbols for this purpose, whose -names are made from the customary ones by adding `__' at the beginning -and end. Thus, the symbol `__vax__' would be available on a Vax, and -so on. - - The set of nonstandard predefined names in the GNU C preprocessor is -controlled (when `cpp' is itself compiled) by the macro -`CPP_PREDEFINES', which should be a string containing `-D' options, -separated by spaces. For example, on the Sun 3, we use the following -definition: - - #define CPP_PREDEFINES "-Dmc68000 -Dsun -Dunix -Dm68k" - -This macro is usually specified in `tm.h'. - - -File: cpp.info, Node: Stringification, Next: Concatenation, Prev: Predefined, Up: Macros - -Stringification ---------------- - - "Stringification" means turning a code fragment into a string -constant whose contents are the text for the code fragment. For -example, stringifying `foo (z)' results in `"foo (z)"'. - - In the C preprocessor, stringification is an option available when -macro arguments are substituted into the macro definition. In the body -of the definition, when an argument name appears, the character `#' -before the name specifies stringification of the corresponding actual -argument when it is substituted at that point in the definition. The -same argument may be substituted in other places in the definition -without stringification if the argument name appears in those places -with no `#'. - - Here is an example of a macro definition that uses stringification: - - #define WARN_IF(EXP) \ - do { if (EXP) \ - fprintf (stderr, "Warning: " #EXP "\n"); } \ - while (0) - -Here the actual argument for `EXP' is substituted once as given, into -the `if' statement, and once as stringified, into the argument to -`fprintf'. The `do' and `while (0)' are a kludge to make it possible -to write `WARN_IF (ARG);', which the resemblance of `WARN_IF' to a -function would make C programmers want to do; see *Note Swallow -Semicolon::. - - The stringification feature is limited to transforming one macro -argument into one string constant: there is no way to combine the -argument with other text and then stringify it all together. But the -example above shows how an equivalent result can be obtained in ANSI -Standard C using the feature that adjacent string constants are -concatenated as one string constant. The preprocessor stringifies the -actual value of `EXP' into a separate string constant, resulting in -text like - - do { if (x == 0) \ - fprintf (stderr, "Warning: " "x == 0" "\n"); } \ - while (0) - -but the C compiler then sees three consecutive string constants and -concatenates them into one, producing effectively - - do { if (x == 0) \ - fprintf (stderr, "Warning: x == 0\n"); } \ - while (0) - - Stringification in C involves more than putting doublequote -characters around the fragment; it is necessary to put backslashes in -front of all doublequote characters, and all backslashes in string and -character constants, in order to get a valid C string constant with the -proper contents. Thus, stringifying `p = "foo\n";' results in `"p = -\"foo\\n\";"'. However, backslashes that are not inside of string or -character constants are not duplicated: `\n' by itself stringifies to -`"\n"'. - - Whitespace (including comments) in the text being stringified is -handled according to precise rules. All leading and trailing -whitespace is ignored. Any sequence of whitespace in the middle of the -text is converted to a single space in the stringified result. - - -File: cpp.info, Node: Concatenation, Next: Undefining, Prev: Stringification, Up: Macros - -Concatenation -------------- - - "Concatenation" means joining two strings into one. In the context -of macro expansion, concatenation refers to joining two lexical units -into one longer one. Specifically, an actual argument to the macro can -be concatenated with another actual argument or with fixed text to -produce a longer name. The longer name might be the name of a function, -variable or type, or a C keyword; it might even be the name of another -macro, in which case it will be expanded. - - When you define a macro, you request concatenation with the special -operator `##' in the macro body. When the macro is called, after -actual arguments are substituted, all `##' operators are deleted, and -so is any whitespace next to them (including whitespace that was part -of an actual argument). The result is to concatenate the syntactic -tokens on either side of the `##'. - - Consider a C program that interprets named commands. There probably -needs to be a table of commands, perhaps an array of structures -declared as follows: - - struct command - { - char *name; - void (*function) (); - }; - - struct command commands[] = - { - { "quit", quit_command}, - { "help", help_command}, - ... - }; - - It would be cleaner not to have to give each command name twice, -once in the string constant and once in the function name. A macro -which takes the name of a command as an argument can make this -unnecessary. The string constant can be created with stringification, -and the function name by concatenating the argument with `_command'. -Here is how it is done: - - #define COMMAND(NAME) { #NAME, NAME ## _command } - - struct command commands[] = - { - COMMAND (quit), - COMMAND (help), - ... - }; - - The usual case of concatenation is concatenating two names (or a -name and a number) into a longer name. But this isn't the only valid -case. It is also possible to concatenate two numbers (or a number and -a name, such as `1.5' and `e3') into a number. Also, multi-character -operators such as `+=' can be formed by concatenation. In some cases -it is even possible to piece together a string constant. However, two -pieces of text that don't together form a valid lexical unit cannot be -concatenated. For example, concatenation with `x' on one side and `+' -on the other is not meaningful because those two characters can't fit -together in any lexical unit of C. The ANSI standard says that such -attempts at concatenation are undefined, but in the GNU C preprocessor -it is well defined: it puts the `x' and `+' side by side with no -particular special results. - - Keep in mind that the C preprocessor converts comments to whitespace -before macros are even considered. Therefore, you cannot create a -comment by concatenating `/' and `*': the `/*' sequence that starts a -comment is not a lexical unit, but rather the beginning of a "long" -space character. Also, you can freely use comments next to a `##' in a -macro definition, or in actual arguments that will be concatenated, -because the comments will be converted to spaces at first sight, and -concatenation will later discard the spaces. - - -File: cpp.info, Node: Undefining, Next: Redefining, Prev: Concatenation, Up: Macros - -Undefining Macros ------------------ - - To "undefine" a macro means to cancel its definition. This is done -with the `#undef' directive. `#undef' is followed by the macro name to -be undefined. - - Like definition, undefinition occurs at a specific point in the -source file, and it applies starting from that point. The name ceases -to be a macro name, and from that point on it is treated by the -preprocessor as if it had never been a macro name. - - For example, - - #define FOO 4 - x = FOO; - #undef FOO - x = FOO; - -expands into - - x = 4; - - x = FOO; - -In this example, `FOO' had better be a variable or function as well as -(temporarily) a macro, in order for the result of the expansion to be -valid C code. - - The same form of `#undef' directive will cancel definitions with -arguments or definitions that don't expect arguments. The `#undef' -directive has no effect when used on a name not currently defined as a -macro. - - -File: cpp.info, Node: Redefining, Next: Macro Pitfalls, Prev: Undefining, Up: Macros - -Redefining Macros ------------------ - - "Redefining" a macro means defining (with `#define') a name that is -already defined as a macro. - - A redefinition is trivial if the new definition is transparently -identical to the old one. You probably wouldn't deliberately write a -trivial redefinition, but they can happen automatically when a header -file is included more than once (*note Header Files::.), so they are -accepted silently and without effect. - - Nontrivial redefinition is considered likely to be an error, so it -provokes a warning message from the preprocessor. However, sometimes it -is useful to change the definition of a macro in mid-compilation. You -can inhibit the warning by undefining the macro with `#undef' before the -second definition. - - In order for a redefinition to be trivial, the new definition must -exactly match the one already in effect, with two possible exceptions: - - * Whitespace may be added or deleted at the beginning or the end. - - * Whitespace may be changed in the middle (but not inside strings). - However, it may not be eliminated entirely, and it may not be added - where there was no whitespace at all. - - Recall that a comment counts as whitespace. - - -File: cpp.info, Node: Macro Pitfalls, Prev: Redefining, Up: Macros - -Pitfalls and Subtleties of Macros ---------------------------------- - - In this section we describe some special rules that apply to macros -and macro expansion, and point out certain cases in which the rules have -counterintuitive consequences that you must watch out for. - -* Menu: - -* Misnesting:: Macros can contain unmatched parentheses. -* Macro Parentheses:: Why apparently superfluous parentheses - may be necessary to avoid incorrect grouping. -* Swallow Semicolon:: Macros that look like functions - but expand into compound statements. -* Side Effects:: Unsafe macros that cause trouble when - arguments contain side effects. -* Self-Reference:: Macros whose definitions use the macros' own names. -* Argument Prescan:: Actual arguments are checked for macro calls - before they are substituted. -* Cascaded Macros:: Macros whose definitions use other macros. -* Newlines in Args:: Sometimes line numbers get confused. - diff --git a/support/cpp/cpp.info-2 b/support/cpp/cpp.info-2 deleted file mode 100644 index 8407c2b3..00000000 --- a/support/cpp/cpp.info-2 +++ /dev/null @@ -1,1032 +0,0 @@ -This is Info file cpp.info, produced by Makeinfo version 1.67 from the -input file cpp.texi. - - This file documents the GNU C Preprocessor. - - Copyright 1987, 1989, 1991, 1992, 1993, 1994, 1995 Free Software -Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided also -that the entire resulting derived work is distributed under the terms -of a permission notice identical to this one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions. - - -File: cpp.info, Node: Misnesting, Next: Macro Parentheses, Prev: Macro Pitfalls, Up: Macro Pitfalls - -Improperly Nested Constructs -............................ - - Recall that when a macro is called with arguments, the arguments are -substituted into the macro body and the result is checked, together with -the rest of the input file, for more macro calls. - - It is possible to piece together a macro call coming partially from -the macro body and partially from the actual arguments. For example, - - #define double(x) (2*(x)) - #define call_with_1(x) x(1) - -would expand `call_with_1 (double)' into `(2*(1))'. - - Macro definitions do not have to have balanced parentheses. By -writing an unbalanced open parenthesis in a macro body, it is possible -to create a macro call that begins inside the macro body but ends -outside of it. For example, - - #define strange(file) fprintf (file, "%s %d", - ... - strange(stderr) p, 35) - -This bizarre example expands to `fprintf (stderr, "%s %d", p, 35)'! - - -File: cpp.info, Node: Macro Parentheses, Next: Swallow Semicolon, Prev: Misnesting, Up: Macro Pitfalls - -Unintended Grouping of Arithmetic -................................. - - You may have noticed that in most of the macro definition examples -shown above, each occurrence of a macro argument name had parentheses -around it. In addition, another pair of parentheses usually surround -the entire macro definition. Here is why it is best to write macros -that way. - - Suppose you define a macro as follows, - - #define ceil_div(x, y) (x + y - 1) / y - -whose purpose is to divide, rounding up. (One use for this operation is -to compute how many `int' objects are needed to hold a certain number -of `char' objects.) Then suppose it is used as follows: - - a = ceil_div (b & c, sizeof (int)); - -This expands into - - a = (b & c + sizeof (int) - 1) / sizeof (int); - -which does not do what is intended. The operator-precedence rules of C -make it equivalent to this: - - a = (b & (c + sizeof (int) - 1)) / sizeof (int); - -But what we want is this: - - a = ((b & c) + sizeof (int) - 1)) / sizeof (int); - -Defining the macro as - - #define ceil_div(x, y) ((x) + (y) - 1) / (y) - -provides the desired result. - - However, unintended grouping can result in another way. Consider -`sizeof ceil_div(1, 2)'. That has the appearance of a C expression -that would compute the size of the type of `ceil_div (1, 2)', but in -fact it means something very different. Here is what it expands to: - - sizeof ((1) + (2) - 1) / (2) - -This would take the size of an integer and divide it by two. The -precedence rules have put the division outside the `sizeof' when it was -intended to be inside. - - Parentheses around the entire macro definition can prevent such -problems. Here, then, is the recommended way to define `ceil_div': - - #define ceil_div(x, y) (((x) + (y) - 1) / (y)) - - -File: cpp.info, Node: Swallow Semicolon, Next: Side Effects, Prev: Macro Parentheses, Up: Macro Pitfalls - -Swallowing the Semicolon -........................ - - Often it is desirable to define a macro that expands into a compound -statement. Consider, for example, the following macro, that advances a -pointer (the argument `p' says where to find it) across whitespace -characters: - - #define SKIP_SPACES (p, limit) \ - { register char *lim = (limit); \ - while (p != lim) { \ - if (*p++ != ' ') { \ - p--; break; }}} - -Here Backslash-Newline is used to split the macro definition, which must -be a single line, so that it resembles the way such C code would be -laid out if not part of a macro definition. - - A call to this macro might be `SKIP_SPACES (p, lim)'. Strictly -speaking, the call expands to a compound statement, which is a complete -statement with no need for a semicolon to end it. But it looks like a -function call. So it minimizes confusion if you can use it like a -function call, writing a semicolon afterward, as in `SKIP_SPACES (p, -lim);' - - But this can cause trouble before `else' statements, because the -semicolon is actually a null statement. Suppose you write - - if (*p != 0) - SKIP_SPACES (p, lim); - else ... - -The presence of two statements--the compound statement and a null -statement--in between the `if' condition and the `else' makes invalid C -code. - - The definition of the macro `SKIP_SPACES' can be altered to solve -this problem, using a `do ... while' statement. Here is how: - - #define SKIP_SPACES (p, limit) \ - do { register char *lim = (limit); \ - while (p != lim) { \ - if (*p++ != ' ') { \ - p--; break; }}} \ - while (0) - - Now `SKIP_SPACES (p, lim);' expands into - - do {...} while (0); - -which is one statement. - - -File: cpp.info, Node: Side Effects, Next: Self-Reference, Prev: Swallow Semicolon, Up: Macro Pitfalls - -Duplication of Side Effects -........................... - - Many C programs define a macro `min', for "minimum", like this: - - #define min(X, Y) ((X) < (Y) ? (X) : (Y)) - - When you use this macro with an argument containing a side effect, -as shown here, - - next = min (x + y, foo (z)); - -it expands as follows: - - next = ((x + y) < (foo (z)) ? (x + y) : (foo (z))); - -where `x + y' has been substituted for `X' and `foo (z)' for `Y'. - - The function `foo' is used only once in the statement as it appears -in the program, but the expression `foo (z)' has been substituted twice -into the macro expansion. As a result, `foo' might be called two times -when the statement is executed. If it has side effects or if it takes -a long time to compute, the results might not be what you intended. We -say that `min' is an "unsafe" macro. - - The best solution to this problem is to define `min' in a way that -computes the value of `foo (z)' only once. The C language offers no -standard way to do this, but it can be done with GNU C extensions as -follows: - - #define min(X, Y) \ - ({ typeof (X) __x = (X), __y = (Y); \ - (__x < __y) ? __x : __y; }) - - If you do not wish to use GNU C extensions, the only solution is to -be careful when *using* the macro `min'. For example, you can -calculate the value of `foo (z)', save it in a variable, and use that -variable in `min': - - #define min(X, Y) ((X) < (Y) ? (X) : (Y)) - ... - { - int tem = foo (z); - next = min (x + y, tem); - } - -(where we assume that `foo' returns type `int'). - - -File: cpp.info, Node: Self-Reference, Next: Argument Prescan, Prev: Side Effects, Up: Macro Pitfalls - -Self-Referential Macros -....................... - - A "self-referential" macro is one whose name appears in its -definition. A special feature of ANSI Standard C is that the -self-reference is not considered a macro call. It is passed into the -preprocessor output unchanged. - - Let's consider an example: - - #define foo (4 + foo) - -where `foo' is also a variable in your program. - - Following the ordinary rules, each reference to `foo' will expand -into `(4 + foo)'; then this will be rescanned and will expand into `(4 -+ (4 + foo))'; and so on until it causes a fatal error (memory full) in -the preprocessor. - - However, the special rule about self-reference cuts this process -short after one step, at `(4 + foo)'. Therefore, this macro definition -has the possibly useful effect of causing the program to add 4 to the -value of `foo' wherever `foo' is referred to. - - In most cases, it is a bad idea to take advantage of this feature. A -person reading the program who sees that `foo' is a variable will not -expect that it is a macro as well. The reader will come across the -identifier `foo' in the program and think its value should be that of -the variable `foo', whereas in fact the value is four greater. - - The special rule for self-reference applies also to "indirect" -self-reference. This is the case where a macro X expands to use a -macro `y', and the expansion of `y' refers to the macro `x'. The -resulting reference to `x' comes indirectly from the expansion of `x', -so it is a self-reference and is not further expanded. Thus, after - - #define x (4 + y) - #define y (2 * x) - -`x' would expand into `(4 + (2 * x))'. Clear? - - But suppose `y' is used elsewhere, not from the definition of `x'. -Then the use of `x' in the expansion of `y' is not a self-reference -because `x' is not "in progress". So it does expand. However, the -expansion of `x' contains a reference to `y', and that is an indirect -self-reference now because `y' is "in progress". The result is that -`y' expands to `(2 * (4 + y))'. - - It is not clear that this behavior would ever be useful, but it is -specified by the ANSI C standard, so you may need to understand it. - - -File: cpp.info, Node: Argument Prescan, Next: Cascaded Macros, Prev: Self-Reference, Up: Macro Pitfalls - -Separate Expansion of Macro Arguments -..................................... - - We have explained that the expansion of a macro, including the -substituted actual arguments, is scanned over again for macro calls to -be expanded. - - What really happens is more subtle: first each actual argument text -is scanned separately for macro calls. Then the results of this are -substituted into the macro body to produce the macro expansion, and the -macro expansion is scanned again for macros to expand. - - The result is that the actual arguments are scanned *twice* to expand -macro calls in them. - - Most of the time, this has no effect. If the actual argument -contained any macro calls, they are expanded during the first scan. -The result therefore contains no macro calls, so the second scan does -not change it. If the actual argument were substituted as given, with -no prescan, the single remaining scan would find the same macro calls -and produce the same results. - - You might expect the double scan to change the results when a -self-referential macro is used in an actual argument of another macro -(*note Self-Reference::.): the self-referential macro would be expanded -once in the first scan, and a second time in the second scan. But this -is not what happens. The self-references that do not expand in the -first scan are marked so that they will not expand in the second scan -either. - - The prescan is not done when an argument is stringified or -concatenated. Thus, - - #define str(s) #s - #define foo 4 - str (foo) - -expands to `"foo"'. Once more, prescan has been prevented from having -any noticeable effect. - - More precisely, stringification and concatenation use the argument as -written, in un-prescanned form. The same actual argument would be used -in prescanned form if it is substituted elsewhere without -stringification or concatenation. - - #define str(s) #s lose(s) - #define foo 4 - str (foo) - - expands to `"foo" lose(4)'. - - You might now ask, "Why mention the prescan, if it makes no -difference? And why not skip it and make the preprocessor faster?" -The answer is that the prescan does make a difference in three special -cases: - - * Nested calls to a macro. - - * Macros that call other macros that stringify or concatenate. - - * Macros whose expansions contain unshielded commas. - - We say that "nested" calls to a macro occur when a macro's actual -argument contains a call to that very macro. For example, if `f' is a -macro that expects one argument, `f (f (1))' is a nested pair of calls -to `f'. The desired expansion is made by expanding `f (1)' and -substituting that into the definition of `f'. The prescan causes the -expected result to happen. Without the prescan, `f (1)' itself would -be substituted as an actual argument, and the inner use of `f' would -appear during the main scan as an indirect self-reference and would not -be expanded. Here, the prescan cancels an undesirable side effect (in -the medical, not computational, sense of the term) of the special rule -for self-referential macros. - - But prescan causes trouble in certain other cases of nested macro -calls. Here is an example: - - #define foo a,b - #define bar(x) lose(x) - #define lose(x) (1 + (x)) - - bar(foo) - -We would like `bar(foo)' to turn into `(1 + (foo))', which would then -turn into `(1 + (a,b))'. But instead, `bar(foo)' expands into -`lose(a,b)', and you get an error because `lose' requires a single -argument. In this case, the problem is easily solved by the same -parentheses that ought to be used to prevent misnesting of arithmetic -operations: - - #define foo (a,b) - #define bar(x) lose((x)) - - The problem is more serious when the operands of the macro are not -expressions; for example, when they are statements. Then parentheses -are unacceptable because they would make for invalid C code: - - #define foo { int a, b; ... } - -In GNU C you can shield the commas using the `({...})' construct which -turns a compound statement into an expression: - - #define foo ({ int a, b; ... }) - - Or you can rewrite the macro definition to avoid such commas: - - #define foo { int a; int b; ... } - - There is also one case where prescan is useful. It is possible to -use prescan to expand an argument and then stringify it--if you use two -levels of macros. Let's add a new macro `xstr' to the example shown -above: - - #define xstr(s) str(s) - #define str(s) #s - #define foo 4 - xstr (foo) - - This expands into `"4"', not `"foo"'. The reason for the difference -is that the argument of `xstr' is expanded at prescan (because `xstr' -does not specify stringification or concatenation of the argument). -The result of prescan then forms the actual argument for `str'. `str' -uses its argument without prescan because it performs stringification; -but it cannot prevent or undo the prescanning already done by `xstr'. - - -File: cpp.info, Node: Cascaded Macros, Next: Newlines in Args, Prev: Argument Prescan, Up: Macro Pitfalls - -Cascaded Use of Macros -...................... - - A "cascade" of macros is when one macro's body contains a reference -to another macro. This is very common practice. For example, - - #define BUFSIZE 1020 - #define TABLESIZE BUFSIZE - - This is not at all the same as defining `TABLESIZE' to be `1020'. -The `#define' for `TABLESIZE' uses exactly the body you specify--in -this case, `BUFSIZE'--and does not check to see whether it too is the -name of a macro. - - It's only when you *use* `TABLESIZE' that the result of its expansion -is checked for more macro names. - - This makes a difference if you change the definition of `BUFSIZE' at -some point in the source file. `TABLESIZE', defined as shown, will -always expand using the definition of `BUFSIZE' that is currently in -effect: - - #define BUFSIZE 1020 - #define TABLESIZE BUFSIZE - #undef BUFSIZE - #define BUFSIZE 37 - -Now `TABLESIZE' expands (in two stages) to `37'. (The `#undef' is to -prevent any warning about the nontrivial redefinition of `BUFSIZE'.) - - -File: cpp.info, Node: Newlines in Args, Prev: Cascaded Macros, Up: Macro Pitfalls - -Newlines in Macro Arguments ---------------------------- - - Traditional macro processing carries forward all newlines in macro -arguments into the expansion of the macro. This means that, if some of -the arguments are substituted more than once, or not at all, or out of -order, newlines can be duplicated, lost, or moved around within the -expansion. If the expansion consists of multiple statements, then the -effect is to distort the line numbers of some of these statements. The -result can be incorrect line numbers, in error messages or displayed in -a debugger. - - The GNU C preprocessor operating in ANSI C mode adjusts appropriately -for multiple use of an argument--the first use expands all the -newlines, and subsequent uses of the same argument produce no newlines. -But even in this mode, it can produce incorrect line numbering if -arguments are used out of order, or not used at all. - - Here is an example illustrating this problem: - - #define ignore_second_arg(a,b,c) a; c - - ignore_second_arg (foo (), - ignored (), - syntax error); - -The syntax error triggered by the tokens `syntax error' results in an -error message citing line four, even though the statement text comes -from line five. - - -File: cpp.info, Node: Conditionals, Next: Combining Sources, Prev: Macros, Up: Top - -Conditionals -============ - - In a macro processor, a "conditional" is a directive that allows a -part of the program to be ignored during compilation, on some -conditions. In the C preprocessor, a conditional can test either an -arithmetic expression or whether a name is defined as a macro. - - A conditional in the C preprocessor resembles in some ways an `if' -statement in C, but it is important to understand the difference between -them. The condition in an `if' statement is tested during the execution -of your program. Its purpose is to allow your program to behave -differently from run to run, depending on the data it is operating on. -The condition in a preprocessing conditional directive is tested when -your program is compiled. Its purpose is to allow different code to be -included in the program depending on the situation at the time of -compilation. - -* Menu: - -* Uses: Conditional Uses. What conditionals are for. -* Syntax: Conditional Syntax. How conditionals are written. -* Deletion: Deleted Code. Making code into a comment. -* Macros: Conditionals-Macros. Why conditionals are used with macros. -* Assertions:: How and why to use assertions. -* Errors: #error Directive. Detecting inconsistent compilation parameters. - - -File: cpp.info, Node: Conditional Uses, Next: Conditional Syntax, Up: Conditionals - -Why Conditionals are Used -------------------------- - - Generally there are three kinds of reason to use a conditional. - - * A program may need to use different code depending on the machine - or operating system it is to run on. In some cases the code for - one operating system may be erroneous on another operating system; - for example, it might refer to library routines that do not exist - on the other system. When this happens, it is not enough to avoid - executing the invalid code: merely having it in the program makes - it impossible to link the program and run it. With a - preprocessing conditional, the offending code can be effectively - excised from the program when it is not valid. - - * You may want to be able to compile the same source file into two - different programs. Sometimes the difference between the programs - is that one makes frequent time-consuming consistency checks on its - intermediate data, or prints the values of those data for - debugging, while the other does not. - - * A conditional whose condition is always false is a good way to - exclude code from the program but keep it as a sort of comment for - future reference. - - Most simple programs that are intended to run on only one machine -will not need to use preprocessing conditionals. - - -File: cpp.info, Node: Conditional Syntax, Next: Deleted Code, Prev: Conditional Uses, Up: Conditionals - -Syntax of Conditionals ----------------------- - - A conditional in the C preprocessor begins with a "conditional -directive": `#if', `#ifdef' or `#ifndef'. *Note Conditionals-Macros::, -for information on `#ifdef' and `#ifndef'; only `#if' is explained here. - -* Menu: - -* If: #if Directive. Basic conditionals using `#if' and `#endif'. -* Else: #else Directive. Including some text if the condition fails. -* Elif: #elif Directive. Testing several alternative possibilities. - - -File: cpp.info, Node: #if Directive, Next: #else Directive, Up: Conditional Syntax - -The `#if' Directive -................... - - The `#if' directive in its simplest form consists of - - #if EXPRESSION - CONTROLLED TEXT - #endif /* EXPRESSION */ - - The comment following the `#endif' is not required, but it is a good -practice because it helps people match the `#endif' to the -corresponding `#if'. Such comments should always be used, except in -short conditionals that are not nested. In fact, you can put anything -at all after the `#endif' and it will be ignored by the GNU C -preprocessor, but only comments are acceptable in ANSI Standard C. - - EXPRESSION is a C expression of integer type, subject to stringent -restrictions. It may contain - - * Integer constants, which are all regarded as `long' or `unsigned - long'. - - * Character constants, which are interpreted according to the - character set and conventions of the machine and operating system - on which the preprocessor is running. The GNU C preprocessor uses - the C data type `char' for these character constants; therefore, - whether some character codes are negative is determined by the C - compiler used to compile the preprocessor. If it treats `char' as - signed, then character codes large enough to set the sign bit will - be considered negative; otherwise, no character code is considered - negative. - - * Arithmetic operators for addition, subtraction, multiplication, - division, bitwise operations, shifts, comparisons, and logical - operations (`&&' and `||'). - - * Identifiers that are not macros, which are all treated as zero(!). - - * Macro calls. All macro calls in the expression are expanded before - actual computation of the expression's value begins. - - Note that `sizeof' operators and `enum'-type values are not allowed. -`enum'-type values, like all other identifiers that are not taken as -macro calls and expanded, are treated as zero. - - The CONTROLLED TEXT inside of a conditional can include -preprocessing directives. Then the directives inside the conditional -are obeyed only if that branch of the conditional succeeds. The text -can also contain other conditional groups. However, the `#if' and -`#endif' directives must balance. - - -File: cpp.info, Node: #else Directive, Next: #elif Directive, Prev: #if Directive, Up: Conditional Syntax - -The `#else' Directive -..................... - - The `#else' directive can be added to a conditional to provide -alternative text to be used if the condition is false. This is what it -looks like: - - #if EXPRESSION - TEXT-IF-TRUE - #else /* Not EXPRESSION */ - TEXT-IF-FALSE - #endif /* Not EXPRESSION */ - - If EXPRESSION is nonzero, and thus the TEXT-IF-TRUE is active, then -`#else' acts like a failing conditional and the TEXT-IF-FALSE is -ignored. Contrariwise, if the `#if' conditional fails, the -TEXT-IF-FALSE is considered included. - - -File: cpp.info, Node: #elif Directive, Prev: #else Directive, Up: Conditional Syntax - -The `#elif' Directive -..................... - - One common case of nested conditionals is used to check for more -than two possible alternatives. For example, you might have - - #if X == 1 - ... - #else /* X != 1 */ - #if X == 2 - ... - #else /* X != 2 */ - ... - #endif /* X != 2 */ - #endif /* X != 1 */ - - Another conditional directive, `#elif', allows this to be abbreviated -as follows: - - #if X == 1 - ... - #elif X == 2 - ... - #else /* X != 2 and X != 1*/ - ... - #endif /* X != 2 and X != 1*/ - - `#elif' stands for "else if". Like `#else', it goes in the middle -of a `#if'-`#endif' pair and subdivides it; it does not require a -matching `#endif' of its own. Like `#if', the `#elif' directive -includes an expression to be tested. - - The text following the `#elif' is processed only if the original -`#if'-condition failed and the `#elif' condition succeeds. More than -one `#elif' can go in the same `#if'-`#endif' group. Then the text -after each `#elif' is processed only if the `#elif' condition succeeds -after the original `#if' and any previous `#elif' directives within it -have failed. `#else' is equivalent to `#elif 1', and `#else' is -allowed after any number of `#elif' directives, but `#elif' may not -follow `#else'. - - -File: cpp.info, Node: Deleted Code, Next: Conditionals-Macros, Prev: Conditional Syntax, Up: Conditionals - -Keeping Deleted Code for Future Reference ------------------------------------------ - - If you replace or delete a part of the program but want to keep the -old code around as a comment for future reference, the easy way to do -this is to put `#if 0' before it and `#endif' after it. This is better -than using comment delimiters `/*' and `*/' since those won't work if -the code already contains comments (C comments do not nest). - - This works even if the code being turned off contains conditionals, -but they must be entire conditionals (balanced `#if' and `#endif'). - - Conversely, do not use `#if 0' for comments which are not C code. -Use the comment delimiters `/*' and `*/' instead. The interior of `#if -0' must consist of complete tokens; in particular, singlequote -characters must balance. But comments often contain unbalanced -singlequote characters (known in English as apostrophes). These -confuse `#if 0'. They do not confuse `/*'. - - -File: cpp.info, Node: Conditionals-Macros, Next: Assertions, Prev: Deleted Code, Up: Conditionals - -Conditionals and Macros ------------------------ - - Conditionals are useful in connection with macros or assertions, -because those are the only ways that an expression's value can vary -from one compilation to another. A `#if' directive whose expression -uses no macros or assertions is equivalent to `#if 1' or `#if 0'; you -might as well determine which one, by computing the value of the -expression yourself, and then simplify the program. - - For example, here is a conditional that tests the expression -`BUFSIZE == 1020', where `BUFSIZE' must be a macro. - - #if BUFSIZE == 1020 - printf ("Large buffers!\n"); - #endif /* BUFSIZE is large */ - - (Programmers often wish they could test the size of a variable or -data type in `#if', but this does not work. The preprocessor does not -understand `sizeof', or typedef names, or even the type keywords such -as `int'.) - - The special operator `defined' is used in `#if' expressions to test -whether a certain name is defined as a macro. Either `defined NAME' or -`defined (NAME)' is an expression whose value is 1 if NAME is defined -as macro at the current point in the program, and 0 otherwise. For the -`defined' operator it makes no difference what the definition of the -macro is; all that matters is whether there is a definition. Thus, for -example, - - #if defined (vax) || defined (ns16000) - -would succeed if either of the names `vax' and `ns16000' is defined as -a macro. You can test the same condition using assertions (*note -Assertions::.), like this: - - #if #cpu (vax) || #cpu (ns16000) - - If a macro is defined and later undefined with `#undef', subsequent -use of the `defined' operator returns 0, because the name is no longer -defined. If the macro is defined again with another `#define', -`defined' will recommence returning 1. - - Conditionals that test whether just one name is defined are very -common, so there are two special short conditional directives for this -case. - -`#ifdef NAME' - is equivalent to `#if defined (NAME)'. - -`#ifndef NAME' - is equivalent to `#if ! defined (NAME)'. - - Macro definitions can vary between compilations for several reasons. - - * Some macros are predefined on each kind of machine. For example, - on a Vax, the name `vax' is a predefined macro. On other - machines, it would not be defined. - - * Many more macros are defined by system header files. Different - systems and machines define different macros, or give them - different values. It is useful to test these macros with - conditionals to avoid using a system feature on a machine where it - is not implemented. - - * Macros are a common way of allowing users to customize a program - for different machines or applications. For example, the macro - `BUFSIZE' might be defined in a configuration file for your - program that is included as a header file in each source file. You - would use `BUFSIZE' in a preprocessing conditional in order to - generate different code depending on the chosen configuration. - - * Macros can be defined or undefined with `-D' and `-U' command - options when you compile the program. You can arrange to compile - the same source file into two different programs by choosing a - macro name to specify which program you want, writing conditionals - to test whether or how this macro is defined, and then controlling - the state of the macro with compiler command options. *Note - Invocation::. - - Assertions are usually predefined, but can be defined with -preprocessor directives or command-line options. - - -File: cpp.info, Node: Assertions, Next: #error Directive, Prev: Conditionals-Macros, Up: Conditionals - -Assertions ----------- - - "Assertions" are a more systematic alternative to macros in writing -conditionals to test what sort of computer or system the compiled -program will run on. Assertions are usually predefined, but you can -define them with preprocessing directives or command-line options. - - The macros traditionally used to describe the type of target are not -classified in any way according to which question they answer; they may -indicate a hardware architecture, a particular hardware model, an -operating system, a particular version of an operating system, or -specific configuration options. These are jumbled together in a single -namespace. In contrast, each assertion consists of a named question and -an answer. The question is usually called the "predicate". An -assertion looks like this: - - #PREDICATE (ANSWER) - -You must use a properly formed identifier for PREDICATE. The value of -ANSWER can be any sequence of words; all characters are significant -except for leading and trailing whitespace, and differences in internal -whitespace sequences are ignored. Thus, `x + y' is different from -`x+y' but equivalent to `x + y'. `)' is not allowed in an answer. - - Here is a conditional to test whether the answer ANSWER is asserted -for the predicate PREDICATE: - - #if #PREDICATE (ANSWER) - -There may be more than one answer asserted for a given predicate. If -you omit the answer, you can test whether *any* answer is asserted for -PREDICATE: - - #if #PREDICATE - - Most of the time, the assertions you test will be predefined -assertions. GNU C provides three predefined predicates: `system', -`cpu', and `machine'. `system' is for assertions about the type of -software, `cpu' describes the type of computer architecture, and -`machine' gives more information about the computer. For example, on a -GNU system, the following assertions would be true: - - #system (gnu) - #system (mach) - #system (mach 3) - #system (mach 3.SUBVERSION) - #system (hurd) - #system (hurd VERSION) - -and perhaps others. The alternatives with more or less version -information let you ask more or less detailed questions about the type -of system software. - - On a Unix system, you would find `#system (unix)' and perhaps one of: -`#system (aix)', `#system (bsd)', `#system (hpux)', `#system (lynx)', -`#system (mach)', `#system (posix)', `#system (svr3)', `#system -(svr4)', or `#system (xpg4)' with possible version numbers following. - - Other values for `system' are `#system (mvs)' and `#system (vms)'. - - *Portability note:* Many Unix C compilers provide only one answer -for the `system' assertion: `#system (unix)', if they support -assertions at all. This is less than useful. - - An assertion with a multi-word answer is completely different from -several assertions with individual single-word answers. For example, -the presence of `system (mach 3.0)' does not mean that `system (3.0)' -is true. It also does not directly imply `system (mach)', but in GNU -C, that last will normally be asserted as well. - - The current list of possible assertion values for `cpu' is: `#cpu -(a29k)', `#cpu (alpha)', `#cpu (arm)', `#cpu (clipper)', `#cpu -(convex)', `#cpu (elxsi)', `#cpu (tron)', `#cpu (h8300)', `#cpu -(i370)', `#cpu (i386)', `#cpu (i860)', `#cpu (i960)', `#cpu (m68k)', -`#cpu (m88k)', `#cpu (mips)', `#cpu (ns32k)', `#cpu (hppa)', `#cpu -(pyr)', `#cpu (ibm032)', `#cpu (rs6000)', `#cpu (sh)', `#cpu (sparc)', -`#cpu (spur)', `#cpu (tahoe)', `#cpu (vax)', `#cpu (we32000)'. - - You can create assertions within a C program using `#assert', like -this: - - #assert PREDICATE (ANSWER) - -(Note the absence of a `#' before PREDICATE.) - - Each time you do this, you assert a new true answer for PREDICATE. -Asserting one answer does not invalidate previously asserted answers; -they all remain true. The only way to remove an assertion is with -`#unassert'. `#unassert' has the same syntax as `#assert'. You can -also remove all assertions about PREDICATE like this: - - #unassert PREDICATE - - You can also add or cancel assertions using command options when you -run `gcc' or `cpp'. *Note Invocation::. - - -File: cpp.info, Node: #error Directive, Prev: Assertions, Up: Conditionals - -The `#error' and `#warning' Directives --------------------------------------- - - The directive `#error' causes the preprocessor to report a fatal -error. The rest of the line that follows `#error' is used as the error -message. - - You would use `#error' inside of a conditional that detects a -combination of parameters which you know the program does not properly -support. For example, if you know that the program will not run -properly on a Vax, you might write - - #ifdef __vax__ - #error Won't work on Vaxen. See comments at get_last_object. - #endif - -*Note Nonstandard Predefined::, for why this works. - - If you have several configuration parameters that must be set up by -the installation in a consistent way, you can use conditionals to detect -an inconsistency and report it with `#error'. For example, - - #if HASH_TABLE_SIZE % 2 == 0 || HASH_TABLE_SIZE % 3 == 0 \ - || HASH_TABLE_SIZE % 5 == 0 - #error HASH_TABLE_SIZE should not be divisible by a small prime - #endif - - The directive `#warning' is like the directive `#error', but causes -the preprocessor to issue a warning and continue preprocessing. The -rest of the line that follows `#warning' is used as the warning message. - - You might use `#warning' in obsolete header files, with a message -directing the user to the header file which should be used instead. - - -File: cpp.info, Node: Combining Sources, Next: Other Directives, Prev: Conditionals, Up: Top - -Combining Source Files -====================== - - One of the jobs of the C preprocessor is to inform the C compiler of -where each line of C code came from: which source file and which line -number. - - C code can come from multiple source files if you use `#include'; -both `#include' and the use of conditionals and macros can cause the -line number of a line in the preprocessor output to be different from -the line's number in the original source file. You will appreciate the -value of making both the C compiler (in error messages) and symbolic -debuggers such as GDB use the line numbers in your source file. - - The C preprocessor builds on this feature by offering a directive by -which you can control the feature explicitly. This is useful when a -file for input to the C preprocessor is the output from another program -such as the `bison' parser generator, which operates on another file -that is the true source file. Parts of the output from `bison' are -generated from scratch, other parts come from a standard parser file. -The rest are copied nearly verbatim from the source file, but their -line numbers in the `bison' output are not the same as their original -line numbers. Naturally you would like compiler error messages and -symbolic debuggers to know the original source file and line number of -each line in the `bison' input. - - `bison' arranges this by writing `#line' directives into the output -file. `#line' is a directive that specifies the original line number -and source file name for subsequent input in the current preprocessor -input file. `#line' has three variants: - -`#line LINENUM' - Here LINENUM is a decimal integer constant. This specifies that - the line number of the following line of input, in its original - source file, was LINENUM. - -`#line LINENUM FILENAME' - Here LINENUM is a decimal integer constant and FILENAME is a - string constant. This specifies that the following line of input - came originally from source file FILENAME and its line number there - was LINENUM. Keep in mind that FILENAME is not just a file name; - it is surrounded by doublequote characters so that it looks like a - string constant. - -`#line ANYTHING ELSE' - ANYTHING ELSE is checked for macro calls, which are expanded. The - result should be a decimal integer constant followed optionally by - a string constant, as described above. - - `#line' directives alter the results of the `__FILE__' and -`__LINE__' predefined macros from that point on. *Note Standard -Predefined::. - - The output of the preprocessor (which is the input for the rest of -the compiler) contains directives that look much like `#line' -directives. They start with just `#' instead of `#line', but this is -followed by a line number and file name as in `#line'. *Note Output::. - - -File: cpp.info, Node: Other Directives, Next: Output, Prev: Combining Sources, Up: Top - -Miscellaneous Preprocessing Directives -====================================== - - This section describes three additional preprocessing directives. -They are not very useful, but are mentioned for completeness. - - The "null directive" consists of a `#' followed by a Newline, with -only whitespace (including comments) in between. A null directive is -understood as a preprocessing directive but has no effect on the -preprocessor output. The primary significance of the existence of the -null directive is that an input line consisting of just a `#' will -produce no output, rather than a line of output containing just a `#'. -Supposedly some old C programs contain such lines. - - The ANSI standard specifies that the `#pragma' directive has an -arbitrary, implementation-defined effect. In the GNU C preprocessor, -`#pragma' directives are not used, except for `#pragma once' (*note -Once-Only::.). However, they are left in the preprocessor output, so -they are available to the compilation pass. - - The `#ident' directive is supported for compatibility with certain -other systems. It is followed by a line of text. On some systems, the -text is copied into a special place in the object file; on most systems, -the text is ignored and this directive has no effect. Typically -`#ident' is only used in header files supplied with those systems where -it is meaningful. - - -File: cpp.info, Node: Output, Next: Invocation, Prev: Other Directives, Up: Top - -C Preprocessor Output -===================== - - The output from the C preprocessor looks much like the input, except -that all preprocessing directive lines have been replaced with blank -lines and all comments with spaces. Whitespace within a line is not -altered; however, a space is inserted after the expansions of most -macro calls. - - Source file name and line number information is conveyed by lines of -the form - - # LINENUM FILENAME FLAGS - -which are inserted as needed into the middle of the input (but never -within a string or character constant). Such a line means that the -following line originated in file FILENAME at line LINENUM. - - After the file name comes zero or more flags, which are `1', `2', -`3', or `4'. If there are multiple flags, spaces separate them. Here -is what the flags mean: - -`1' - This indicates the start of a new file. - -`2' - This indicates returning to a file (after having included another - file). - -`3' - This indicates that the following text comes from a system header - file, so certain warnings should be suppressed. - -`4' - This indicates that the following text should be treated as C. - diff --git a/support/cpp/cpp.info-3 b/support/cpp/cpp.info-3 deleted file mode 100644 index 30fa3116..00000000 --- a/support/cpp/cpp.info-3 +++ /dev/null @@ -1,466 +0,0 @@ -This is Info file cpp.info, produced by Makeinfo version 1.67 from the -input file cpp.texi. - - This file documents the GNU C Preprocessor. - - Copyright 1987, 1989, 1991, 1992, 1993, 1994, 1995 Free Software -Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided also -that the entire resulting derived work is distributed under the terms -of a permission notice identical to this one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions. - - -File: cpp.info, Node: Invocation, Next: Concept Index, Prev: Output, Up: Top - -Invoking the C Preprocessor -=========================== - - Most often when you use the C preprocessor you will not have to -invoke it explicitly: the C compiler will do so automatically. -However, the preprocessor is sometimes useful on its own. - - The C preprocessor expects two file names as arguments, INFILE and -OUTFILE. The preprocessor reads INFILE together with any other files -it specifies with `#include'. All the output generated by the combined -input files is written in OUTFILE. - - Either INFILE or OUTFILE may be `-', which as INFILE means to read -from standard input and as OUTFILE means to write to standard output. -Also, if OUTFILE or both file names are omitted, the standard output -and standard input are used for the omitted file names. - - Here is a table of command options accepted by the C preprocessor. -These options can also be given when compiling a C program; they are -passed along automatically to the preprocessor when it is invoked by the -compiler. - -`-P' - Inhibit generation of `#'-lines with line-number information in - the output from the preprocessor (*note Output::.). This might be - useful when running the preprocessor on something that is not C - code and will be sent to a program which might be confused by the - `#'-lines. - -`-C' - Do not discard comments: pass them through to the output file. - Comments appearing in arguments of a macro call will be copied to - the output before the expansion of the macro call. - -`-traditional' - Try to imitate the behavior of old-fashioned C, as opposed to ANSI - C. - - * Traditional macro expansion pays no attention to singlequote - or doublequote characters; macro argument symbols are - replaced by the argument values even when they appear within - apparent string or character constants. - - * Traditionally, it is permissible for a macro expansion to end - in the middle of a string or character constant. The - constant continues into the text surrounding the macro call. - - * However, traditionally the end of the line terminates a - string or character constant, with no error. - - * In traditional C, a comment is equivalent to no text at all. - (In ANSI C, a comment counts as whitespace.) - - * Traditional C does not have the concept of a "preprocessing - number". It considers `1.0e+4' to be three tokens: `1.0e', - `+', and `4'. - - * A macro is not suppressed within its own definition, in - traditional C. Thus, any macro that is used recursively - inevitably causes an error. - - * The character `#' has no special meaning within a macro - definition in traditional C. - - * In traditional C, the text at the end of a macro expansion - can run together with the text after the macro call, to - produce a single token. (This is impossible in ANSI C.) - - * Traditionally, `\' inside a macro argument suppresses the - syntactic significance of the following character. - -`-trigraphs' - Process ANSI standard trigraph sequences. These are - three-character sequences, all starting with `??', that are - defined by ANSI C to stand for single characters. For example, - `??/' stands for `\', so `'??/n'' is a character constant for a - newline. Strictly speaking, the GNU C preprocessor does not - support all programs in ANSI Standard C unless `-trigraphs' is - used, but if you ever notice the difference it will be with relief. - - You don't want to know any more about trigraphs. - -`-pedantic' - Issue warnings required by the ANSI C standard in certain cases - such as when text other than a comment follows `#else' or `#endif'. - -`-pedantic-errors' - Like `-pedantic', except that errors are produced rather than - warnings. - -`-Wtrigraphs' - Warn if any trigraphs are encountered (assuming they are enabled). - -`-Wcomment' - Warn whenever a comment-start sequence `/*' appears in a comment. - -`-Wall' - Requests both `-Wtrigraphs' and `-Wcomment' (but not - `-Wtraditional'). - -`-Wtraditional' - Warn about certain constructs that behave differently in - traditional and ANSI C. - -`-I DIRECTORY' - Add the directory DIRECTORY to the head of the list of directories - to be searched for header files (*note Include Syntax::.). This - can be used to override a system header file, substituting your - own version, since these directories are searched before the system - header file directories. If you use more than one `-I' option, - the directories are scanned in left-to-right order; the standard - system directories come after. - -`-I-' - Any directories specified with `-I' options before the `-I-' - option are searched only for the case of `#include "FILE"'; they - are not searched for `#include '. - - If additional directories are specified with `-I' options after - the `-I-', these directories are searched for all `#include' - directives. - - In addition, the `-I-' option inhibits the use of the current - directory as the first search directory for `#include "FILE"'. - Therefore, the current directory is searched only if it is - requested explicitly with `-I.'. Specifying both `-I-' and `-I.' - allows you to control precisely which directories are searched - before the current one and which are searched after. - -`-nostdinc' - Do not search the standard system directories for header files. - Only the directories you have specified with `-I' options (and the - current directory, if appropriate) are searched. - -`-nostdinc++' - Do not search for header files in the C++-specific standard - directories, but do still search the other standard directories. - (This option is used when building libg++.) - -`-D NAME' - Predefine NAME as a macro, with definition `1'. - -`-D NAME=DEFINITION' - Predefine NAME as a macro, with definition DEFINITION. There are - no restrictions on the contents of DEFINITION, but if you are - invoking the preprocessor from a shell or shell-like program you - may need to use the shell's quoting syntax to protect characters - such as spaces that have a meaning in the shell syntax. If you - use more than one `-D' for the same NAME, the rightmost definition - takes effect. - -`-U NAME' - Do not predefine NAME. If both `-U' and `-D' are specified for - one name, the `-U' beats the `-D' and the name is not predefined. - -`-undef' - Do not predefine any nonstandard macros. - -`-A PREDICATE(ANSWER)' - Make an assertion with the predicate PREDICATE and answer ANSWER. - *Note Assertions::. - - You can use `-A-' to disable all predefined assertions; it also - undefines all predefined macros that identify the type of target - system. - -`-dM' - Instead of outputting the result of preprocessing, output a list of - `#define' directives for all the macros defined during the - execution of the preprocessor, including predefined macros. This - gives you a way of finding out what is predefined in your version - of the preprocessor; assuming you have no file `foo.h', the command - - touch foo.h; cpp -dM foo.h - - will show the values of any predefined macros. - -`-dD' - Like `-dM' except in two respects: it does *not* include the - predefined macros, and it outputs *both* the `#define' directives - and the result of preprocessing. Both kinds of output go to the - standard output file. - -`-M [-MG]' - Instead of outputting the result of preprocessing, output a rule - suitable for `make' describing the dependencies of the main source - file. The preprocessor outputs one `make' rule containing the - object file name for that source file, a colon, and the names of - all the included files. If there are many included files then the - rule is split into several lines using `\'-newline. - - `-MG' says to treat missing header files as generated files and - assume they live in the same directory as the source file. It - must be specified in addition to `-M'. - - This feature is used in automatic updating of makefiles. - -`-MM [-MG]' - Like `-M' but mention only the files included with `#include - "FILE"'. System header files included with `#include ' are - omitted. - -`-MD FILE' - Like `-M' but the dependency information is written to FILE. This - is in addition to compiling the file as specified--`-MD' does not - inhibit ordinary compilation the way `-M' does. - - When invoking gcc, do not specify the FILE argument. Gcc will - create file names made by replacing ".c" with ".d" at the end of - the input file names. - - In Mach, you can use the utility `md' to merge multiple dependency - files into a single dependency file suitable for using with the - `make' command. - -`-MMD FILE' - Like `-MD' except mention only user header files, not system - header files. - -`-H' - Print the name of each header file used, in addition to other - normal activities. - -`-imacros FILE' - Process FILE as input, discarding the resulting output, before - processing the regular input file. Because the output generated - from FILE is discarded, the only effect of `-imacros FILE' is to - make the macros defined in FILE available for use in the main - input. - -`-include FILE' - Process FILE as input, and include all the resulting output, - before processing the regular input file. - -`-idirafter DIR' - Add the directory DIR to the second include path. The directories - on the second include path are searched when a header file is not - found in any of the directories in the main include path (the one - that `-I' adds to). - -`-iprefix PREFIX' - Specify PREFIX as the prefix for subsequent `-iwithprefix' options. - -`-iwithprefix DIR' - Add a directory to the second include path. The directory's name - is made by concatenating PREFIX and DIR, where PREFIX was - specified previously with `-iprefix'. - -`-isystem DIR' - Add a directory to the beginning of the second include path, - marking it as a system directory, so that it gets the same special - treatment as is applied to the standard system directories. - -`-lang-c' -`-lang-c89' -`-lang-c++' -`-lang-objc' -`-lang-objc++' - Specify the source language. `-lang-c' is the default; it allows - recognition of C++ comments (comments that begin with `//' and end - at end of line), since this is a common feature and it will most - likely be in the next C standard. `-lang-c89' disables - recognition of C++ comments. `-lang-c++' handles C++ comment - syntax and includes extra default include directories for C++. - `-lang-objc' enables the Objective C `#import' directive. - `-lang-objc++' enables both C++ and Objective C extensions. - - These options are generated by the compiler driver `gcc', but not - passed from the `gcc' command line unless you use the driver's - `-Wp' option. - -`-lint' - Look for commands to the program checker `lint' embedded in - comments, and emit them preceded by `#pragma lint'. For example, - the comment `/* NOTREACHED */' becomes `#pragma lint NOTREACHED'. - - This option is available only when you call `cpp' directly; `gcc' - will not pass it from its command line. - -`-$' - Forbid the use of `$' in identifiers. This is required for ANSI - conformance. `gcc' automatically supplies this option to the - preprocessor if you specify `-ansi', but `gcc' doesn't recognize - the `-$' option itself--to use it without the other effects of - `-ansi', you must call the preprocessor directly. - - -File: cpp.info, Node: Concept Index, Next: Index, Prev: Invocation, Up: Top - -Concept Index -************* - -* Menu: - -* ##: Concatenation. -* arguments in macro definitions: Argument Macros. -* assertions: Assertions. -* assertions, undoing: Assertions. -* blank macro arguments: Argument Macros. -* cascaded macros: Cascaded Macros. -* commenting out code: Deleted Code. -* computed #include: Include Syntax. -* concatenation: Concatenation. -* conditionals: Conditionals. -* directives: Directives. -* expansion of arguments: Argument Prescan. -* function-like macro: Argument Macros. -* header file: Header Files. -* including just once: Once-Only. -* inheritance: Inheritance. -* invocation of the preprocessor: Invocation. -* line control: Combining Sources. -* macro argument expansion: Argument Prescan. -* macro body uses macro: Cascaded Macros. -* macros with argument: Argument Macros. -* manifest constant: Simple Macros. -* newlines in macro arguments: Newlines in Args. -* null directive: Other Directives. -* options: Invocation. -* output format: Output. -* overriding a header file: Inheritance. -* parentheses in macro bodies: Macro Parentheses. -* pitfalls of macros: Macro Pitfalls. -* predefined macros: Predefined. -* predicates: Assertions. -* preprocessing directives: Directives. -* prescan of macro arguments: Argument Prescan. -* problems with macros: Macro Pitfalls. -* redefining macros: Redefining. -* repeated inclusion: Once-Only. -* retracting assertions: Assertions. -* second include path: Invocation. -* self-reference: Self-Reference. -* semicolons (after macro calls): Swallow Semicolon. -* side effects (in macro arguments): Side Effects. -* simple macro: Simple Macros. -* space as macro argument: Argument Macros. -* standard predefined macros: Standard Predefined. -* stringification: Stringification. -* testing predicates: Assertions. -* unassert: Assertions. -* undefining macros: Undefining. -* unsafe macros: Side Effects. - - -File: cpp.info, Node: Index, Prev: Concept Index, Up: Top - -Index of Directives, Macros and Options -*************************************** - -* Menu: - -* #assert: Assertions. -* #cpu: Assertions. -* #define: Argument Macros. -* #elif: #elif Directive. -* #else: #else Directive. -* #error: #error Directive. -* #ident: Other Directives. -* #if: Conditional Syntax. -* #ifdef: Conditionals-Macros. -* #ifndef: Conditionals-Macros. -* #import: Once-Only. -* #include: Include Syntax. -* #include_next: Inheritance. -* #line: Combining Sources. -* #machine: Assertions. -* #pragma: Other Directives. -* #pragma once: Once-Only. -* #system: Assertions. -* #unassert: Assertions. -* #warning: #error Directive. -* -$: Invocation. -* -A: Invocation. -* -C: Invocation. -* -D: Invocation. -* -dD: Invocation. -* -dM: Invocation. -* -H: Invocation. -* -I: Invocation. -* -idirafter: Invocation. -* -imacros: Invocation. -* -include: Invocation. -* -iprefix: Invocation. -* -isystem: Invocation. -* -iwithprefix: Invocation. -* -lang-c: Invocation. -* -lang-c++: Invocation. -* -lang-c89: Invocation. -* -lang-objc: Invocation. -* -lang-objc++: Invocation. -* -M: Invocation. -* -MD: Invocation. -* -MM: Invocation. -* -MMD: Invocation. -* -nostdinc: Invocation. -* -nostdinc++: Invocation. -* -P: Invocation. -* -pedantic: Invocation. -* -pedantic-errors: Invocation. -* -traditional: Invocation. -* -trigraphs: Invocation. -* -U: Invocation. -* -undef: Invocation. -* -Wall: Invocation. -* -Wcomment: Invocation. -* -Wtraditional: Invocation. -* -Wtrigraphs: Invocation. -* __BASE_FILE__: Standard Predefined. -* __CHAR_UNSIGNED__: Standard Predefined. -* __cplusplus: Standard Predefined. -* __DATE__: Standard Predefined. -* __FILE__: Standard Predefined. -* __GNUC__: Standard Predefined. -* __GNUC_MINOR__: Standard Predefined. -* __GNUG__: Standard Predefined. -* __INCLUDE_LEVEL_: Standard Predefined. -* __LINE__: Standard Predefined. -* __OPTIMIZE__: Standard Predefined. -* __REGISTER_PREFIX__: Standard Predefined. -* __STDC__: Standard Predefined. -* __STDC_VERSION__: Standard Predefined. -* __STRICT_ANSI__: Standard Predefined. -* __TIME__: Standard Predefined. -* __USER_LABEL_PREFIX__: Standard Predefined. -* __VERSION__: Standard Predefined. -* _AM29000: Nonstandard Predefined. -* _AM29K: Nonstandard Predefined. -* BSD: Nonstandard Predefined. -* defined: Conditionals-Macros. -* M68020: Nonstandard Predefined. -* m68k: Nonstandard Predefined. -* mc68000: Nonstandard Predefined. -* ns32000: Nonstandard Predefined. -* pyr: Nonstandard Predefined. -* sequent: Nonstandard Predefined. -* sun: Nonstandard Predefined. -* system header files: Header Uses. -* unix: Nonstandard Predefined. -* vax: Nonstandard Predefined. - - diff --git a/support/cpp/cpp.texi b/support/cpp/cpp.texi deleted file mode 100644 index 1de83717..00000000 --- a/support/cpp/cpp.texi +++ /dev/null @@ -1,2856 +0,0 @@ -\input texinfo -@setfilename cpp.info -@settitle The C Preprocessor - -@ignore -@ifinfo -@format -START-INFO-DIR-ENTRY -* Cpp: (cpp). The C preprocessor. -END-INFO-DIR-ENTRY -@end format -@end ifinfo -@end ignore - -@c @smallbook -@c @cropmarks -@c @finalout -@setchapternewpage odd -@ifinfo -This file documents the GNU C Preprocessor. - -Copyright 1987, 1989, 1991, 1992, 1993, 1994, 1995 Free Software -Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -@ignore -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -@end ignore -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end ifinfo - -@titlepage -@c @finalout -@title The C Preprocessor -@subtitle Last revised July 1992 -@subtitle for GCC version 2 -@author Richard M. Stallman -@page -@vskip 2pc -This booklet is eventually intended to form the first chapter of a GNU -C Language manual. - -@vskip 0pt plus 1filll -Copyright @copyright{} 1987, 1989, 1991, 1992, 1993, 1994, 1995 Free -Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end titlepage -@page - -@node Top, Global Actions,, (DIR) -@chapter The C Preprocessor - -The C preprocessor is a @dfn{macro processor} that is used automatically by -the C compiler to transform your program before actual compilation. It is -called a macro processor because it allows you to define @dfn{macros}, -which are brief abbreviations for longer constructs. - -The C preprocessor provides four separate facilities that you can use as -you see fit: - -@itemize @bullet -@item -Inclusion of header files. These are files of declarations that can be -substituted into your program. - -@item -Macro expansion. You can define @dfn{macros}, which are abbreviations -for arbitrary fragments of C code, and then the C preprocessor will -replace the macros with their definitions throughout the program. - -@item -Conditional compilation. Using special preprocessing directives, you -can include or exclude parts of the program according to various -conditions. - -@item -Line control. If you use a program to combine or rearrange source files into -an intermediate file which is then compiled, you can use line control -to inform the compiler of where each source line originally came from. -@end itemize - -C preprocessors vary in some details. This manual discusses the GNU C -preprocessor, the C Compatible Compiler Preprocessor. The GNU C -preprocessor provides a superset of the features of ANSI Standard C. - -ANSI Standard C requires the rejection of many harmless constructs commonly -used by today's C programs. Such incompatibility would be inconvenient for -users, so the GNU C preprocessor is configured to accept these constructs -by default. Strictly speaking, to get ANSI Standard C, you must use the -options @samp{-trigraphs}, @samp{-undef} and @samp{-pedantic}, but in -practice the consequences of having strict ANSI Standard C make it -undesirable to do this. @xref{Invocation}. - -@menu -* Global Actions:: Actions made uniformly on all input files. -* Directives:: General syntax of preprocessing directives. -* Header Files:: How and why to use header files. -* Macros:: How and why to use macros. -* Conditionals:: How and why to use conditionals. -* Combining Sources:: Use of line control when you combine source files. -* Other Directives:: Miscellaneous preprocessing directives. -* Output:: Format of output from the C preprocessor. -* Invocation:: How to invoke the preprocessor; command options. -* Concept Index:: Index of concepts and terms. -* Index:: Index of directives, predefined macros and options. -@end menu - -@node Global Actions, Directives, Top, Top -@section Transformations Made Globally - -Most C preprocessor features are inactive unless you give specific directives -to request their use. (Preprocessing directives are lines starting with -@samp{#}; @pxref{Directives}). But there are three transformations that the -preprocessor always makes on all the input it receives, even in the absence -of directives. - -@itemize @bullet -@item -All C comments are replaced with single spaces. - -@item -Backslash-Newline sequences are deleted, no matter where. This -feature allows you to break long lines for cosmetic purposes without -changing their meaning. - -@item -Predefined macro names are replaced with their expansions -(@pxref{Predefined}). -@end itemize - -The first two transformations are done @emph{before} nearly all other parsing -and before preprocessing directives are recognized. Thus, for example, you -can split a line cosmetically with Backslash-Newline anywhere (except -when trigraphs are in use; see below). - -@example -/* -*/ # /* -*/ defi\ -ne FO\ -O 10\ -20 -@end example - -@noindent -is equivalent into @samp{#define FOO 1020}. You can split even an escape -sequence with Backslash-Newline. For example, you can split @code{"foo\bar"} -between the @samp{\} and the @samp{b} to get - -@example -"foo\\ -bar" -@end example - -@noindent -This behavior is unclean: in all other contexts, a Backslash can be -inserted in a string constant as an ordinary character by writing a double -Backslash, and this creates an exception. But the ANSI C standard requires -it. (Strict ANSI C does not allow Newlines in string constants, so they -do not consider this a problem.) - -But there are a few exceptions to all three transformations. - -@itemize @bullet -@item -C comments and predefined macro names are not recognized inside a -@samp{#include} directive in which the file name is delimited with -@samp{<} and @samp{>}. - -@item -C comments and predefined macro names are never recognized within a -character or string constant. (Strictly speaking, this is the rule, -not an exception, but it is worth noting here anyway.) - -@item -Backslash-Newline may not safely be used within an ANSI ``trigraph''. -Trigraphs are converted before Backslash-Newline is deleted. If you -write what looks like a trigraph with a Backslash-Newline inside, the -Backslash-Newline is deleted as usual, but it is then too late to -recognize the trigraph. - -This exception is relevant only if you use the @samp{-trigraphs} -option to enable trigraph processing. @xref{Invocation}. -@end itemize - -@node Directives, Header Files, Global Actions, Top -@section Preprocessing Directives - -@cindex preprocessing directives -@cindex directives -Most preprocessor features are active only if you use preprocessing directives -to request their use. - -Preprocessing directives are lines in your program that start with @samp{#}. -The @samp{#} is followed by an identifier that is the @dfn{directive name}. -For example, @samp{#define} is the directive that defines a macro. -Whitespace is also allowed before and after the @samp{#}. - -The set of valid directive names is fixed. Programs cannot define new -preprocessing directives. - -Some directive names require arguments; these make up the rest of the directive -line and must be separated from the directive name by whitespace. For example, -@samp{#define} must be followed by a macro name and the intended expansion -of the macro. @xref{Simple Macros}. - -A preprocessing directive cannot be more than one line in normal circumstances. -It may be split cosmetically with Backslash-Newline, but that has no effect -on its meaning. Comments containing Newlines can also divide the -directive into multiple lines, but the comments are changed to Spaces -before the directive is interpreted. The only way a significant Newline -can occur in a preprocessing directive is within a string constant or -character constant. Note that -most C compilers that might be applied to the output from the preprocessor -do not accept string or character constants containing Newlines. - -The @samp{#} and the directive name cannot come from a macro expansion. For -example, if @samp{foo} is defined as a macro expanding to @samp{define}, -that does not make @samp{#foo} a valid preprocessing directive. - -@node Header Files, Macros, Directives, Top -@section Header Files - -@cindex header file -A header file is a file containing C declarations and macro definitions -(@pxref{Macros}) to be shared between several source files. You request -the use of a header file in your program with the C preprocessing directive -@samp{#include}. - -@menu -* Header Uses:: What header files are used for. -* Include Syntax:: How to write @samp{#include} directives. -* Include Operation:: What @samp{#include} does. -* Once-Only:: Preventing multiple inclusion of one header file. -* Inheritance:: Including one header file in another header file. -@end menu - -@node Header Uses, Include Syntax, Header Files, Header Files -@subsection Uses of Header Files - -Header files serve two kinds of purposes. - -@itemize @bullet -@item -@findex system header files -System header files declare the interfaces to parts of the operating -system. You include them in your program to supply the definitions and -declarations you need to invoke system calls and libraries. - -@item -Your own header files contain declarations for interfaces between the -source files of your program. Each time you have a group of related -declarations and macro definitions all or most of which are needed in -several different source files, it is a good idea to create a header -file for them. -@end itemize - -Including a header file produces the same results in C compilation as -copying the header file into each source file that needs it. But such -copying would be time-consuming and error-prone. With a header file, the -related declarations appear in only one place. If they need to be changed, -they can be changed in one place, and programs that include the header file -will automatically use the new version when next recompiled. The header -file eliminates the labor of finding and changing all the copies as well as -the risk that a failure to find one copy will result in inconsistencies -within a program. - -The usual convention is to give header files names that end with -@file{.h}. Avoid unusual characters in header file names, as they -reduce portability. - -@node Include Syntax, Include Operation, Header Uses, Header Files -@subsection The @samp{#include} Directive - -@findex #include -Both user and system header files are included using the preprocessing -directive @samp{#include}. It has three variants: - -@table @code -@item #include <@var{file}> -This variant is used for system header files. It searches for a file -named @var{file} in a list of directories specified by you, then in a -standard list of system directories. You specify directories to -search for header files with the command option @samp{-I} -(@pxref{Invocation}). The option @samp{-nostdinc} inhibits searching -the standard system directories; in this case only the directories -you specify are searched. - -The parsing of this form of @samp{#include} is slightly special -because comments are not recognized within the @samp{<@dots{}>}. -Thus, in @samp{#include } the @samp{/*} does not start a comment -and the directive specifies inclusion of a system header file named -@file{x/*y}. Of course, a header file with such a name is unlikely to -exist on Unix, where shell wildcard features would make it hard to -manipulate.@refill - -The argument @var{file} may not contain a @samp{>} character. It may, -however, contain a @samp{<} character. - -@item #include "@var{file}" -This variant is used for header files of your own program. It -searches for a file named @var{file} first in the current directory, -then in the same directories used for system header files. The -current directory is the directory of the current input file. It is -tried first because it is presumed to be the location of the files -that the current input file refers to. (If the @samp{-I-} option is -used, the special treatment of the current directory is inhibited.) - -The argument @var{file} may not contain @samp{"} characters. If -backslashes occur within @var{file}, they are considered ordinary text -characters, not escape characters. None of the character escape -sequences appropriate to string constants in C are processed. Thus, -@samp{#include "x\n\\y"} specifies a filename containing three -backslashes. It is not clear why this behavior is ever useful, but -the ANSI standard specifies it. - -@item #include @var{anything else} -@cindex computed @samp{#include} -This variant is called a @dfn{computed #include}. Any @samp{#include} -directive whose argument does not fit the above two forms is a computed -include. The text @var{anything else} is checked for macro calls, -which are expanded (@pxref{Macros}). When this is done, the result -must fit one of the above two variants---in particular, the expanded -text must in the end be surrounded by either quotes or angle braces. - -This feature allows you to define a macro which controls the file name -to be used at a later point in the program. One application of this is -to allow a site-specific configuration file for your program to specify -the names of the system include files to be used. This can help in -porting the program to various operating systems in which the necessary -system header files are found in different places. -@end table - -@node Include Operation, Once-Only, Include Syntax, Header Files -@subsection How @samp{#include} Works - -The @samp{#include} directive works by directing the C preprocessor to scan -the specified file as input before continuing with the rest of the current -file. The output from the preprocessor contains the output already -generated, followed by the output resulting from the included file, -followed by the output that comes from the text after the @samp{#include} -directive. For example, given a header file @file{header.h} as follows, - -@example -char *test (); -@end example - -@noindent -and a main program called @file{program.c} that uses the header file, -like this, - -@example -int x; -#include "header.h" - -main () -@{ - printf (test ()); -@} -@end example - -@noindent -the output generated by the C preprocessor for @file{program.c} as input -would be - -@example -int x; -char *test (); - -main () -@{ - printf (test ()); -@} -@end example - -Included files are not limited to declarations and macro definitions; those -are merely the typical uses. Any fragment of a C program can be included -from another file. The include file could even contain the beginning of a -statement that is concluded in the containing file, or the end of a -statement that was started in the including file. However, a comment or a -string or character constant may not start in the included file and finish -in the including file. An unterminated comment, string constant or -character constant in an included file is considered to end (with an error -message) at the end of the file. - -It is possible for a header file to begin or end a syntactic unit such -as a function definition, but that would be very confusing, so don't do -it. - -The line following the @samp{#include} directive is always treated as a -separate line by the C preprocessor even if the included file lacks a final -newline. - -@node Once-Only, Inheritance, Include Operation, Header Files -@subsection Once-Only Include Files -@cindex repeated inclusion -@cindex including just once - -Very often, one header file includes another. It can easily result that a -certain header file is included more than once. This may lead to errors, -if the header file defines structure types or typedefs, and is certainly -wasteful. Therefore, we often wish to prevent multiple inclusion of a -header file. - -The standard way to do this is to enclose the entire real contents of the -file in a conditional, like this: - -@example -#ifndef FILE_FOO_SEEN -#define FILE_FOO_SEEN - -@var{the entire file} - -#endif /* FILE_FOO_SEEN */ -@end example - -The macro @code{FILE_FOO_SEEN} indicates that the file has been included -once already. In a user header file, the macro name should not begin -with @samp{_}. In a system header file, this name should begin with -@samp{__} to avoid conflicts with user programs. In any kind of header -file, the macro name should contain the name of the file and some -additional text, to avoid conflicts with other header files. - -The GNU C preprocessor is programmed to notice when a header file uses -this particular construct and handle it efficiently. If a header file -is contained entirely in a @samp{#ifndef} conditional, then it records -that fact. If a subsequent @samp{#include} specifies the same file, -and the macro in the @samp{#ifndef} is already defined, then the file -is entirely skipped, without even reading it. - -@findex #pragma once -There is also an explicit directive to tell the preprocessor that it need -not include a file more than once. This is called @samp{#pragma once}, -and was used @emph{in addition to} the @samp{#ifndef} conditional around -the contents of the header file. @samp{#pragma once} is now obsolete -and should not be used at all. - -@findex #import -In the Objective C language, there is a variant of @samp{#include} -called @samp{#import} which includes a file, but does so at most once. -If you use @samp{#import} @emph{instead of} @samp{#include}, then you -don't need the conditionals inside the header file to prevent multiple -execution of the contents. - -@samp{#import} is obsolete because it is not a well designed feature. -It requires the users of a header file---the applications -programmers---to know that a certain header file should only be included -once. It is much better for the header file's implementor to write the -file so that users don't need to know this. Using @samp{#ifndef} -accomplishes this goal. - -@node Inheritance,, Once-Only, Header Files -@subsection Inheritance and Header Files -@cindex inheritance -@cindex overriding a header file - -@dfn{Inheritance} is what happens when one object or file derives some -of its contents by virtual copying from another object or file. In -the case of C header files, inheritance means that one header file -includes another header file and then replaces or adds something. - -If the inheriting header file and the base header file have different -names, then inheritance is straightforward: simply write @samp{#include -"@var{base}"} in the inheriting file. - -Sometimes it is necessary to give the inheriting file the same name as -the base file. This is less straightforward. - -For example, suppose an application program uses the system header file -@file{sys/signal.h}, but the version of @file{/usr/include/sys/signal.h} -on a particular system doesn't do what the application program expects. -It might be convenient to define a ``local'' version, perhaps under the -name @file{/usr/local/include/sys/signal.h}, to override or add to the -one supplied by the system. - -You can do this by using the option @samp{-I.} for compilation, and -writing a file @file{sys/signal.h} that does what the application -program expects. But making this file include the standard -@file{sys/signal.h} is not so easy---writing @samp{#include -} in that file doesn't work, because it includes your own -version of the file, not the standard system version. Used in that file -itself, this leads to an infinite recursion and a fatal error in -compilation. - -@samp{#include } would find the proper file, -but that is not clean, since it makes an assumption about where the -system header file is found. This is bad for maintenance, since it -means that any change in where the system's header files are kept -requires a change somewhere else. - -@findex #include_next -The clean way to solve this problem is to use -@samp{#include_next}, which means, ``Include the @emph{next} file with -this name.'' This directive works like @samp{#include} except in -searching for the specified file: it starts searching the list of header -file directories @emph{after} the directory in which the current file -was found. - -Suppose you specify @samp{-I /usr/local/include}, and the list of -directories to search also includes @file{/usr/include}; and suppose that -both directories contain a file named @file{sys/signal.h}. Ordinary -@samp{#include } finds the file under -@file{/usr/local/include}. If that file contains @samp{#include_next -}, it starts searching after that directory, and finds the -file in @file{/usr/include}. - -@node Macros, Conditionals, Header Files, Top -@section Macros - -A macro is a sort of abbreviation which you can define once and then -use later. There are many complicated features associated with macros -in the C preprocessor. - -@menu -* Simple Macros:: Macros that always expand the same way. -* Argument Macros:: Macros that accept arguments that are substituted - into the macro expansion. -* Predefined:: Predefined macros that are always available. -* Stringification:: Macro arguments converted into string constants. -* Concatenation:: Building tokens from parts taken from macro arguments. -* Undefining:: Cancelling a macro's definition. -* Redefining:: Changing a macro's definition. -* Macro Pitfalls:: Macros can confuse the unwary. Here we explain - several common problems and strange features. -@end menu - -@node Simple Macros, Argument Macros, Macros, Macros -@subsection Simple Macros -@cindex simple macro -@cindex manifest constant - -A @dfn{simple macro} is a kind of abbreviation. It is a name which -stands for a fragment of code. Some people refer to these as -@dfn{manifest constants}. - -Before you can use a macro, you must @dfn{define} it explicitly with the -@samp{#define} directive. @samp{#define} is followed by the name of the -macro and then the code it should be an abbreviation for. For example, - -@example -#define BUFFER_SIZE 1020 -@end example - -@noindent -defines a macro named @samp{BUFFER_SIZE} as an abbreviation for the text -@samp{1020}. If somewhere after this @samp{#define} directive there comes -a C statement of the form - -@example -foo = (char *) xmalloc (BUFFER_SIZE); -@end example - -@noindent -then the C preprocessor will recognize and @dfn{expand} the macro -@samp{BUFFER_SIZE}, resulting in - -@example -foo = (char *) xmalloc (1020); -@end example - -The use of all upper case for macro names is a standard convention. -Programs are easier to read when it is possible to tell at a glance which -names are macros. - -Normally, a macro definition must be a single line, like all C -preprocessing directives. (You can split a long macro definition -cosmetically with Backslash-Newline.) There is one exception: Newlines -can be included in the macro definition if within a string or character -constant. This is because it is not possible for a macro definition to -contain an unbalanced quote character; the definition automatically -extends to include the matching quote character that ends the string or -character constant. Comments within a macro definition may contain -Newlines, which make no difference since the comments are entirely -replaced with Spaces regardless of their contents. - -Aside from the above, there is no restriction on what can go in a macro -body. Parentheses need not balance. The body need not resemble valid C -code. (But if it does not, you may get error messages from the C -compiler when you use the macro.) - -The C preprocessor scans your program sequentially, so macro definitions -take effect at the place you write them. Therefore, the following input to -the C preprocessor - -@example -foo = X; -#define X 4 -bar = X; -@end example - -@noindent -produces as output - -@example -foo = X; - -bar = 4; -@end example - -After the preprocessor expands a macro name, the macro's definition body is -appended to the front of the remaining input, and the check for macro calls -continues. Therefore, the macro body can contain calls to other macros. -For example, after - -@example -#define BUFSIZE 1020 -#define TABLESIZE BUFSIZE -@end example - -@noindent -the name @samp{TABLESIZE} when used in the program would go through two -stages of expansion, resulting ultimately in @samp{1020}. - -This is not at all the same as defining @samp{TABLESIZE} to be @samp{1020}. -The @samp{#define} for @samp{TABLESIZE} uses exactly the body you -specify---in this case, @samp{BUFSIZE}---and does not check to see whether -it too is the name of a macro. It's only when you @emph{use} @samp{TABLESIZE} -that the result of its expansion is checked for more macro names. -@xref{Cascaded Macros}. - -@node Argument Macros, Predefined, Simple Macros, Macros -@subsection Macros with Arguments -@cindex macros with argument -@cindex arguments in macro definitions -@cindex function-like macro - -A simple macro always stands for exactly the same text, each time it is -used. Macros can be more flexible when they accept @dfn{arguments}. -Arguments are fragments of code that you supply each time the macro is -used. These fragments are included in the expansion of the macro -according to the directions in the macro definition. A macro that -accepts arguments is called a @dfn{function-like macro} because the -syntax for using it looks like a function call. - -@findex #define -To define a macro that uses arguments, you write a @samp{#define} directive -with a list of @dfn{argument names} in parentheses after the name of the -macro. The argument names may be any valid C identifiers, separated by -commas and optionally whitespace. The open-parenthesis must follow the -macro name immediately, with no space in between. - -For example, here is a macro that computes the minimum of two numeric -values, as it is defined in many C programs: - -@example -#define min(X, Y) ((X) < (Y) ? (X) : (Y)) -@end example - -@noindent -(This is not the best way to define a ``minimum'' macro in GNU C. -@xref{Side Effects}, for more information.) - -To use a macro that expects arguments, you write the name of the macro -followed by a list of @dfn{actual arguments} in parentheses, separated by -commas. The number of actual arguments you give must match the number of -arguments the macro expects. Examples of use of the macro @samp{min} -include @samp{min (1, 2)} and @samp{min (x + 28, *p)}. - -The expansion text of the macro depends on the arguments you use. -Each of the argument names of the macro is replaced, throughout the -macro definition, with the corresponding actual argument. Using the -same macro @samp{min} defined above, @samp{min (1, 2)} expands into - -@example -((1) < (2) ? (1) : (2)) -@end example - -@noindent -where @samp{1} has been substituted for @samp{X} and @samp{2} for @samp{Y}. - -Likewise, @samp{min (x + 28, *p)} expands into - -@example -((x + 28) < (*p) ? (x + 28) : (*p)) -@end example - -Parentheses in the actual arguments must balance; a comma within -parentheses does not end an argument. However, there is no requirement -for brackets or braces to balance, and they do not prevent a comma from -separating arguments. Thus, - -@example -macro (array[x = y, x + 1]) -@end example - -@noindent -passes two arguments to @code{macro}: @samp{array[x = y} and @samp{x + -1]}. If you want to supply @samp{array[x = y, x + 1]} as an argument, -you must write it as @samp{array[(x = y, x + 1)]}, which is equivalent C -code. - -After the actual arguments are substituted into the macro body, the entire -result is appended to the front of the remaining input, and the check for -macro calls continues. Therefore, the actual arguments can contain calls -to other macros, either with or without arguments, or even to the same -macro. The macro body can also contain calls to other macros. For -example, @samp{min (min (a, b), c)} expands into this text: - -@example -((((a) < (b) ? (a) : (b))) < (c) - ? (((a) < (b) ? (a) : (b))) - : (c)) -@end example - -@noindent -(Line breaks shown here for clarity would not actually be generated.) - -@cindex blank macro arguments -@cindex space as macro argument -If a macro @code{foo} takes one argument, and you want to supply an -empty argument, you must write at least some whitespace between the -parentheses, like this: @samp{foo ( )}. Just @samp{foo ()} is providing -no arguments, which is an error if @code{foo} expects an argument. But -@samp{foo0 ()} is the correct way to call a macro defined to take zero -arguments, like this: - -@example -#define foo0() @dots{} -@end example - -If you use the macro name followed by something other than an -open-parenthesis (after ignoring any spaces, tabs and comments that -follow), it is not a call to the macro, and the preprocessor does not -change what you have written. Therefore, it is possible for the same name -to be a variable or function in your program as well as a macro, and you -can choose in each instance whether to refer to the macro (if an actual -argument list follows) or the variable or function (if an argument list -does not follow). - -Such dual use of one name could be confusing and should be avoided -except when the two meanings are effectively synonymous: that is, when the -name is both a macro and a function and the two have similar effects. You -can think of the name simply as a function; use of the name for purposes -other than calling it (such as, to take the address) will refer to the -function, while calls will expand the macro and generate better but -equivalent code. For example, you can use a function named @samp{min} in -the same source file that defines the macro. If you write @samp{&min} with -no argument list, you refer to the function. If you write @samp{min (x, -bb)}, with an argument list, the macro is expanded. If you write -@samp{(min) (a, bb)}, where the name @samp{min} is not followed by an -open-parenthesis, the macro is not expanded, so you wind up with a call to -the function @samp{min}. - -You may not define the same name as both a simple macro and a macro with -arguments. - -In the definition of a macro with arguments, the list of argument names -must follow the macro name immediately with no space in between. If there -is a space after the macro name, the macro is defined as taking no -arguments, and all the rest of the line is taken to be the expansion. The -reason for this is that it is often useful to define a macro that takes no -arguments and whose definition begins with an identifier in parentheses. -This rule about spaces makes it possible for you to do either this: - -@example -#define FOO(x) - 1 / (x) -@end example - -@noindent -(which defines @samp{FOO} to take an argument and expand into minus the -reciprocal of that argument) or this: - -@example -#define BAR (x) - 1 / (x) -@end example - -@noindent -(which defines @samp{BAR} to take no argument and always expand into -@samp{(x) - 1 / (x)}). - -Note that the @emph{uses} of a macro with arguments can have spaces before -the left parenthesis; it's the @emph{definition} where it matters whether -there is a space. - -@node Predefined, Stringification, Argument Macros, Macros -@subsection Predefined Macros - -@cindex predefined macros -Several simple macros are predefined. You can use them without giving -definitions for them. They fall into two classes: standard macros and -system-specific macros. - -@menu -* Standard Predefined:: Standard predefined macros. -* Nonstandard Predefined:: Nonstandard predefined macros. -@end menu - -@node Standard Predefined, Nonstandard Predefined, Predefined, Predefined -@subsubsection Standard Predefined Macros -@cindex standard predefined macros - -The standard predefined macros are available with the same meanings -regardless of the machine or operating system on which you are using GNU C. -Their names all start and end with double underscores. Those preceding -@code{__GNUC__} in this table are standardized by ANSI C; the rest are -GNU C extensions. - -@table @code -@item __FILE__ -@findex __FILE__ -This macro expands to the name of the current input file, in the form of -a C string constant. The precise name returned is the one that was -specified in @samp{#include} or as the input file name argument. - -@item __LINE__ -@findex __LINE__ -This macro expands to the current input line number, in the form of a -decimal integer constant. While we call it a predefined macro, it's -a pretty strange macro, since its ``definition'' changes with each -new line of source code. - -This and @samp{__FILE__} are useful in generating an error message to -report an inconsistency detected by the program; the message can state -the source line at which the inconsistency was detected. For example, - -@smallexample -fprintf (stderr, "Internal error: " - "negative string length " - "%d at %s, line %d.", - length, __FILE__, __LINE__); -@end smallexample - -A @samp{#include} directive changes the expansions of @samp{__FILE__} -and @samp{__LINE__} to correspond to the included file. At the end of -that file, when processing resumes on the input file that contained -the @samp{#include} directive, the expansions of @samp{__FILE__} and -@samp{__LINE__} revert to the values they had before the -@samp{#include} (but @samp{__LINE__} is then incremented by one as -processing moves to the line after the @samp{#include}). - -The expansions of both @samp{__FILE__} and @samp{__LINE__} are altered -if a @samp{#line} directive is used. @xref{Combining Sources}. - -@item __DATE__ -@findex __DATE__ -This macro expands to a string constant that describes the date on -which the preprocessor is being run. The string constant contains -eleven characters and looks like @samp{"Jan 29 1987"} or @w{@samp{"Apr -1 1905"}}. - -@item __TIME__ -@findex __TIME__ -This macro expands to a string constant that describes the time at -which the preprocessor is being run. The string constant contains -eight characters and looks like @samp{"23:59:01"}. - -@item __STDC__ -@findex __STDC__ -This macro expands to the constant 1, to signify that this is ANSI -Standard C. (Whether that is actually true depends on what C compiler -will operate on the output from the preprocessor.) - -@item __STDC_VERSION__ -@findex __STDC_VERSION__ -This macro expands to the C Standard's version number, -a long integer constant of the form @samp{@var{yyyy}@var{mm}L} -where @var{yyyy} and @var{mm} are the year and month of the Standard version. -This signifies which version of the C Standard the preprocessor conforms to. -Like @samp{__STDC__}, whether this version number is accurate -for the entire implementation depends on what C compiler -will operate on the output from the preprocessor. - -@item __GNUC__ -@findex __GNUC__ -This macro is defined if and only if this is GNU C. This macro is -defined only when the entire GNU C compiler is in use; if you invoke the -preprocessor directly, @samp{__GNUC__} is undefined. The value -identifies the major version number of GNU CC (@samp{1} for GNU CC -version 1, which is now obsolete, and @samp{2} for version 2). - -@item __GNUC_MINOR__ -@findex __GNUC_MINOR__ -The macro contains the minor version number of the compiler. This can -be used to work around differences between different releases of the -compiler (for example, if gcc 2.6.3 is known to support a feature, you -can test for @code{__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 6)}). -The last number, @samp{3} in the -example above, denotes the bugfix level of the compiler; no macro -contains this value. - -@item __GNUG__ -@findex __GNUG__ -The GNU C compiler defines this when the compilation language is -C++; use @samp{__GNUG__} to distinguish between GNU C and GNU -C++. - -@item __cplusplus -@findex __cplusplus -The draft ANSI standard for C++ used to require predefining this -variable. Though it is no longer required, GNU C++ continues to define -it, as do other popular C++ compilers. You can use @samp{__cplusplus} -to test whether a header is compiled by a C compiler or a C++ compiler. - -@item __STRICT_ANSI__ -@findex __STRICT_ANSI__ -This macro is defined if and only if the @samp{-ansi} switch was -specified when GNU C was invoked. Its definition is the null string. -This macro exists primarily to direct certain GNU header files not to -define certain traditional Unix constructs which are incompatible with -ANSI C. - -@item __BASE_FILE__ -@findex __BASE_FILE__ -This macro expands to the name of the main input file, in the form -of a C string constant. This is the source file that was specified -as an argument when the C compiler was invoked. - -@item __INCLUDE_LEVEL__ -@findex __INCLUDE_LEVEL_ -This macro expands to a decimal integer constant that represents the -depth of nesting in include files. The value of this macro is -incremented on every @samp{#include} directive and decremented at every -end of file. For input files specified by command line arguments, -the nesting level is zero. - -@item __VERSION__ -@findex __VERSION__ -This macro expands to a string which describes the version number of -GNU C. The string is normally a sequence of decimal numbers separated -by periods, such as @samp{"2.6.0"}. The only reasonable use of this -macro is to incorporate it into a string constant. - -@item __OPTIMIZE__ -@findex __OPTIMIZE__ -This macro is defined in optimizing compilations. It causes certain -GNU header files to define alternative macro definitions for some -system library functions. It is unwise to refer to or test the -definition of this macro unless you make very sure that programs will -execute with the same effect regardless. - -@item __CHAR_UNSIGNED__ -@findex __CHAR_UNSIGNED__ -This macro is defined if and only if the data type @code{char} is -unsigned on the target machine. It exists to cause the standard -header file @file{limit.h} to work correctly. It is bad practice -to refer to this macro yourself; instead, refer to the standard -macros defined in @file{limit.h}. The preprocessor uses -this macro to determine whether or not to sign-extend large character -constants written in octal; see @ref{#if Directive,,The @samp{#if} Directive}. - -@item __REGISTER_PREFIX__ -@findex __REGISTER_PREFIX__ -This macro expands to a string describing the prefix applied to cpu -registers in assembler code. It can be used to write assembler code -that is usable in multiple environments. For example, in the -@samp{m68k-aout} environment it expands to the string @samp{""}, -but in the @samp{m68k-coff} environment it expands to the string -@samp{"%"}. - -@item __USER_LABEL_PREFIX__ -@findex __USER_LABEL_PREFIX__ -This macro expands to a string describing the prefix applied to -user generated labels in assembler code. It can be used to write -assembler code that is usable in multiple environments. -For example, in the @samp{m68k-aout} environment it expands to the -string @samp{"_"}, but in the @samp{m68k-coff} environment it expands -to the string @samp{""}. -@end table - -@node Nonstandard Predefined,, Standard Predefined, Predefined -@subsubsection Nonstandard Predefined Macros - -The C preprocessor normally has several predefined macros that vary between -machines because their purpose is to indicate what type of system and -machine is in use. This manual, being for all systems and machines, cannot -tell you exactly what their names are; instead, we offer a list of some -typical ones. You can use @samp{cpp -dM} to see the values of -predefined macros; see @ref{Invocation}. - -Some nonstandard predefined macros describe the operating system in use, -with more or less specificity. For example, - -@table @code -@item unix -@findex unix -@samp{unix} is normally predefined on all Unix systems. - -@item BSD -@findex BSD -@samp{BSD} is predefined on recent versions of Berkeley Unix -(perhaps only in version 4.3). -@end table - -Other nonstandard predefined macros describe the kind of CPU, with more or -less specificity. For example, - -@table @code -@item vax -@findex vax -@samp{vax} is predefined on Vax computers. - -@item mc68000 -@findex mc68000 -@samp{mc68000} is predefined on most computers whose CPU is a Motorola -68000, 68010 or 68020. - -@item m68k -@findex m68k -@samp{m68k} is also predefined on most computers whose CPU is a 68000, -68010 or 68020; however, some makers use @samp{mc68000} and some use -@samp{m68k}. Some predefine both names. What happens in GNU C -depends on the system you are using it on. - -@item M68020 -@findex M68020 -@samp{M68020} has been observed to be predefined on some systems that -use 68020 CPUs---in addition to @samp{mc68000} and @samp{m68k}, which -are less specific. - -@item _AM29K -@findex _AM29K -@itemx _AM29000 -@findex _AM29000 -Both @samp{_AM29K} and @samp{_AM29000} are predefined for the AMD 29000 -CPU family. - -@item ns32000 -@findex ns32000 -@samp{ns32000} is predefined on computers which use the National -Semiconductor 32000 series CPU. -@end table - -Yet other nonstandard predefined macros describe the manufacturer of -the system. For example, - -@table @code -@item sun -@findex sun -@samp{sun} is predefined on all models of Sun computers. - -@item pyr -@findex pyr -@samp{pyr} is predefined on all models of Pyramid computers. - -@item sequent -@findex sequent -@samp{sequent} is predefined on all models of Sequent computers. -@end table - -These predefined symbols are not only nonstandard, they are contrary to the -ANSI standard because their names do not start with underscores. -Therefore, the option @samp{-ansi} inhibits the definition of these -symbols. - -This tends to make @samp{-ansi} useless, since many programs depend on the -customary nonstandard predefined symbols. Even system header files check -them and will generate incorrect declarations if they do not find the names -that are expected. You might think that the header files supplied for the -Uglix computer would not need to test what machine they are running on, -because they can simply assume it is the Uglix; but often they do, and they -do so using the customary names. As a result, very few C programs will -compile with @samp{-ansi}. We intend to avoid such problems on the GNU -system. - -What, then, should you do in an ANSI C program to test the type of machine -it will run on? - -GNU C offers a parallel series of symbols for this purpose, whose names -are made from the customary ones by adding @samp{__} at the beginning -and end. Thus, the symbol @code{__vax__} would be available on a Vax, -and so on. - -The set of nonstandard predefined names in the GNU C preprocessor is -controlled (when @code{cpp} is itself compiled) by the macro -@samp{CPP_PREDEFINES}, which should be a string containing @samp{-D} -options, separated by spaces. For example, on the Sun 3, we use the -following definition: - -@example -#define CPP_PREDEFINES "-Dmc68000 -Dsun -Dunix -Dm68k" -@end example - -@noindent -This macro is usually specified in @file{tm.h}. - -@node Stringification, Concatenation, Predefined, Macros -@subsection Stringification - -@cindex stringification -@dfn{Stringification} means turning a code fragment into a string constant -whose contents are the text for the code fragment. For example, -stringifying @samp{foo (z)} results in @samp{"foo (z)"}. - -In the C preprocessor, stringification is an option available when macro -arguments are substituted into the macro definition. In the body of the -definition, when an argument name appears, the character @samp{#} before -the name specifies stringification of the corresponding actual argument -when it is substituted at that point in the definition. The same argument -may be substituted in other places in the definition without -stringification if the argument name appears in those places with no -@samp{#}. - -Here is an example of a macro definition that uses stringification: - -@smallexample -@group -#define WARN_IF(EXP) \ -do @{ if (EXP) \ - fprintf (stderr, "Warning: " #EXP "\n"); @} \ -while (0) -@end group -@end smallexample - -@noindent -Here the actual argument for @samp{EXP} is substituted once as given, -into the @samp{if} statement, and once as stringified, into the -argument to @samp{fprintf}. The @samp{do} and @samp{while (0)} are -a kludge to make it possible to write @samp{WARN_IF (@var{arg});}, -which the resemblance of @samp{WARN_IF} to a function would make -C programmers want to do; see @ref{Swallow Semicolon}. - -The stringification feature is limited to transforming one macro argument -into one string constant: there is no way to combine the argument with -other text and then stringify it all together. But the example above shows -how an equivalent result can be obtained in ANSI Standard C using the -feature that adjacent string constants are concatenated as one string -constant. The preprocessor stringifies the actual value of @samp{EXP} -into a separate string constant, resulting in text like - -@smallexample -@group -do @{ if (x == 0) \ - fprintf (stderr, "Warning: " "x == 0" "\n"); @} \ -while (0) -@end group -@end smallexample - -@noindent -but the C compiler then sees three consecutive string constants and -concatenates them into one, producing effectively - -@smallexample -do @{ if (x == 0) \ - fprintf (stderr, "Warning: x == 0\n"); @} \ -while (0) -@end smallexample - -Stringification in C involves more than putting doublequote characters -around the fragment; it is necessary to put backslashes in front of all -doublequote characters, and all backslashes in string and character -constants, in order to get a valid C string constant with the proper -contents. Thus, stringifying @samp{p = "foo\n";} results in @samp{"p = -\"foo\\n\";"}. However, backslashes that are not inside of string or -character constants are not duplicated: @samp{\n} by itself stringifies to -@samp{"\n"}. - -Whitespace (including comments) in the text being stringified is handled -according to precise rules. All leading and trailing whitespace is ignored. -Any sequence of whitespace in the middle of the text is converted to -a single space in the stringified result. - -@node Concatenation, Undefining, Stringification, Macros -@subsection Concatenation -@cindex concatenation -@cindex @samp{##} -@dfn{Concatenation} means joining two strings into one. In the context -of macro expansion, concatenation refers to joining two lexical units -into one longer one. Specifically, an actual argument to the macro can be -concatenated with another actual argument or with fixed text to produce -a longer name. The longer name might be the name of a function, -variable or type, or a C keyword; it might even be the name of another -macro, in which case it will be expanded. - -When you define a macro, you request concatenation with the special -operator @samp{##} in the macro body. When the macro is called, -after actual arguments are substituted, all @samp{##} operators are -deleted, and so is any whitespace next to them (including whitespace -that was part of an actual argument). The result is to concatenate -the syntactic tokens on either side of the @samp{##}. - -Consider a C program that interprets named commands. There probably needs -to be a table of commands, perhaps an array of structures declared as -follows: - -@example -struct command -@{ - char *name; - void (*function) (); -@}; - -struct command commands[] = -@{ - @{ "quit", quit_command@}, - @{ "help", help_command@}, - @dots{} -@}; -@end example - -It would be cleaner not to have to give each command name twice, once in -the string constant and once in the function name. A macro which takes the -name of a command as an argument can make this unnecessary. The string -constant can be created with stringification, and the function name by -concatenating the argument with @samp{_command}. Here is how it is done: - -@example -#define COMMAND(NAME) @{ #NAME, NAME ## _command @} - -struct command commands[] = -@{ - COMMAND (quit), - COMMAND (help), - @dots{} -@}; -@end example - -The usual case of concatenation is concatenating two names (or a name and a -number) into a longer name. But this isn't the only valid case. It is -also possible to concatenate two numbers (or a number and a name, such as -@samp{1.5} and @samp{e3}) into a number. Also, multi-character operators -such as @samp{+=} can be formed by concatenation. In some cases it is even -possible to piece together a string constant. However, two pieces of text -that don't together form a valid lexical unit cannot be concatenated. For -example, concatenation with @samp{x} on one side and @samp{+} on the other -is not meaningful because those two characters can't fit together in any -lexical unit of C. The ANSI standard says that such attempts at -concatenation are undefined, but in the GNU C preprocessor it is well -defined: it puts the @samp{x} and @samp{+} side by side with no particular -special results. - -Keep in mind that the C preprocessor converts comments to whitespace before -macros are even considered. Therefore, you cannot create a comment by -concatenating @samp{/} and @samp{*}: the @samp{/*} sequence that starts a -comment is not a lexical unit, but rather the beginning of a ``long'' space -character. Also, you can freely use comments next to a @samp{##} in a -macro definition, or in actual arguments that will be concatenated, because -the comments will be converted to spaces at first sight, and concatenation -will later discard the spaces. - -@node Undefining, Redefining, Concatenation, Macros -@subsection Undefining Macros - -@cindex undefining macros -To @dfn{undefine} a macro means to cancel its definition. This is done -with the @samp{#undef} directive. @samp{#undef} is followed by the macro -name to be undefined. - -Like definition, undefinition occurs at a specific point in the source -file, and it applies starting from that point. The name ceases to be a -macro name, and from that point on it is treated by the preprocessor as if -it had never been a macro name. - -For example, - -@example -#define FOO 4 -x = FOO; -#undef FOO -x = FOO; -@end example - -@noindent -expands into - -@example -x = 4; - -x = FOO; -@end example - -@noindent -In this example, @samp{FOO} had better be a variable or function as well -as (temporarily) a macro, in order for the result of the expansion to be -valid C code. - -The same form of @samp{#undef} directive will cancel definitions with -arguments or definitions that don't expect arguments. The @samp{#undef} -directive has no effect when used on a name not currently defined as a macro. - -@node Redefining, Macro Pitfalls, Undefining, Macros -@subsection Redefining Macros - -@cindex redefining macros -@dfn{Redefining} a macro means defining (with @samp{#define}) a name that -is already defined as a macro. - -A redefinition is trivial if the new definition is transparently identical -to the old one. You probably wouldn't deliberately write a trivial -redefinition, but they can happen automatically when a header file is -included more than once (@pxref{Header Files}), so they are accepted -silently and without effect. - -Nontrivial redefinition is considered likely to be an error, so -it provokes a warning message from the preprocessor. However, sometimes it -is useful to change the definition of a macro in mid-compilation. You can -inhibit the warning by undefining the macro with @samp{#undef} before the -second definition. - -In order for a redefinition to be trivial, the new definition must -exactly match the one already in effect, with two possible exceptions: - -@itemize @bullet -@item -Whitespace may be added or deleted at the beginning or the end. - -@item -Whitespace may be changed in the middle (but not inside strings). -However, it may not be eliminated entirely, and it may not be added -where there was no whitespace at all. -@end itemize - -Recall that a comment counts as whitespace. - -@node Macro Pitfalls,, Redefining, Macros -@subsection Pitfalls and Subtleties of Macros -@cindex problems with macros -@cindex pitfalls of macros - -In this section we describe some special rules that apply to macros and -macro expansion, and point out certain cases in which the rules have -counterintuitive consequences that you must watch out for. - -@menu -* Misnesting:: Macros can contain unmatched parentheses. -* Macro Parentheses:: Why apparently superfluous parentheses - may be necessary to avoid incorrect grouping. -* Swallow Semicolon:: Macros that look like functions - but expand into compound statements. -* Side Effects:: Unsafe macros that cause trouble when - arguments contain side effects. -* Self-Reference:: Macros whose definitions use the macros' own names. -* Argument Prescan:: Actual arguments are checked for macro calls - before they are substituted. -* Cascaded Macros:: Macros whose definitions use other macros. -* Newlines in Args:: Sometimes line numbers get confused. -@end menu - -@node Misnesting, Macro Parentheses, Macro Pitfalls, Macro Pitfalls -@subsubsection Improperly Nested Constructs - -Recall that when a macro is called with arguments, the arguments are -substituted into the macro body and the result is checked, together with -the rest of the input file, for more macro calls. - -It is possible to piece together a macro call coming partially from the -macro body and partially from the actual arguments. For example, - -@example -#define double(x) (2*(x)) -#define call_with_1(x) x(1) -@end example - -@noindent -would expand @samp{call_with_1 (double)} into @samp{(2*(1))}. - -Macro definitions do not have to have balanced parentheses. By writing an -unbalanced open parenthesis in a macro body, it is possible to create a -macro call that begins inside the macro body but ends outside of it. For -example, - -@example -#define strange(file) fprintf (file, "%s %d", -@dots{} -strange(stderr) p, 35) -@end example - -@noindent -This bizarre example expands to @samp{fprintf (stderr, "%s %d", p, 35)}! - -@node Macro Parentheses, Swallow Semicolon, Misnesting, Macro Pitfalls -@subsubsection Unintended Grouping of Arithmetic -@cindex parentheses in macro bodies - -You may have noticed that in most of the macro definition examples shown -above, each occurrence of a macro argument name had parentheses around it. -In addition, another pair of parentheses usually surround the entire macro -definition. Here is why it is best to write macros that way. - -Suppose you define a macro as follows, - -@example -#define ceil_div(x, y) (x + y - 1) / y -@end example - -@noindent -whose purpose is to divide, rounding up. (One use for this operation is -to compute how many @samp{int} objects are needed to hold a certain -number of @samp{char} objects.) Then suppose it is used as follows: - -@example -a = ceil_div (b & c, sizeof (int)); -@end example - -@noindent -This expands into - -@example -a = (b & c + sizeof (int) - 1) / sizeof (int); -@end example - -@noindent -which does not do what is intended. The operator-precedence rules of -C make it equivalent to this: - -@example -a = (b & (c + sizeof (int) - 1)) / sizeof (int); -@end example - -@noindent -But what we want is this: - -@example -a = ((b & c) + sizeof (int) - 1)) / sizeof (int); -@end example - -@noindent -Defining the macro as - -@example -#define ceil_div(x, y) ((x) + (y) - 1) / (y) -@end example - -@noindent -provides the desired result. - -However, unintended grouping can result in another way. Consider -@samp{sizeof ceil_div(1, 2)}. That has the appearance of a C expression -that would compute the size of the type of @samp{ceil_div (1, 2)}, but in -fact it means something very different. Here is what it expands to: - -@example -sizeof ((1) + (2) - 1) / (2) -@end example - -@noindent -This would take the size of an integer and divide it by two. The precedence -rules have put the division outside the @samp{sizeof} when it was intended -to be inside. - -Parentheses around the entire macro definition can prevent such problems. -Here, then, is the recommended way to define @samp{ceil_div}: - -@example -#define ceil_div(x, y) (((x) + (y) - 1) / (y)) -@end example - -@node Swallow Semicolon, Side Effects, Macro Parentheses, Macro Pitfalls -@subsubsection Swallowing the Semicolon - -@cindex semicolons (after macro calls) -Often it is desirable to define a macro that expands into a compound -statement. Consider, for example, the following macro, that advances a -pointer (the argument @samp{p} says where to find it) across whitespace -characters: - -@example -#define SKIP_SPACES (p, limit) \ -@{ register char *lim = (limit); \ - while (p != lim) @{ \ - if (*p++ != ' ') @{ \ - p--; break; @}@}@} -@end example - -@noindent -Here Backslash-Newline is used to split the macro definition, which must -be a single line, so that it resembles the way such C code would be -laid out if not part of a macro definition. - -A call to this macro might be @samp{SKIP_SPACES (p, lim)}. Strictly -speaking, the call expands to a compound statement, which is a complete -statement with no need for a semicolon to end it. But it looks like a -function call. So it minimizes confusion if you can use it like a function -call, writing a semicolon afterward, as in @samp{SKIP_SPACES (p, lim);} - -But this can cause trouble before @samp{else} statements, because the -semicolon is actually a null statement. Suppose you write - -@example -if (*p != 0) - SKIP_SPACES (p, lim); -else @dots{} -@end example - -@noindent -The presence of two statements---the compound statement and a null -statement---in between the @samp{if} condition and the @samp{else} -makes invalid C code. - -The definition of the macro @samp{SKIP_SPACES} can be altered to solve -this problem, using a @samp{do @dots{} while} statement. Here is how: - -@example -#define SKIP_SPACES (p, limit) \ -do @{ register char *lim = (limit); \ - while (p != lim) @{ \ - if (*p++ != ' ') @{ \ - p--; break; @}@}@} \ -while (0) -@end example - -Now @samp{SKIP_SPACES (p, lim);} expands into - -@example -do @{@dots{}@} while (0); -@end example - -@noindent -which is one statement. - -@node Side Effects, Self-Reference, Swallow Semicolon, Macro Pitfalls -@subsubsection Duplication of Side Effects - -@cindex side effects (in macro arguments) -@cindex unsafe macros -Many C programs define a macro @samp{min}, for ``minimum'', like this: - -@example -#define min(X, Y) ((X) < (Y) ? (X) : (Y)) -@end example - -When you use this macro with an argument containing a side effect, -as shown here, - -@example -next = min (x + y, foo (z)); -@end example - -@noindent -it expands as follows: - -@example -next = ((x + y) < (foo (z)) ? (x + y) : (foo (z))); -@end example - -@noindent -where @samp{x + y} has been substituted for @samp{X} and @samp{foo (z)} -for @samp{Y}. - -The function @samp{foo} is used only once in the statement as it appears -in the program, but the expression @samp{foo (z)} has been substituted -twice into the macro expansion. As a result, @samp{foo} might be called -two times when the statement is executed. If it has side effects or -if it takes a long time to compute, the results might not be what you -intended. We say that @samp{min} is an @dfn{unsafe} macro. - -The best solution to this problem is to define @samp{min} in a way that -computes the value of @samp{foo (z)} only once. The C language offers no -standard way to do this, but it can be done with GNU C extensions as -follows: - -@example -#define min(X, Y) \ -(@{ typeof (X) __x = (X), __y = (Y); \ - (__x < __y) ? __x : __y; @}) -@end example - -If you do not wish to use GNU C extensions, the only solution is to be -careful when @emph{using} the macro @samp{min}. For example, you can -calculate the value of @samp{foo (z)}, save it in a variable, and use that -variable in @samp{min}: - -@example -#define min(X, Y) ((X) < (Y) ? (X) : (Y)) -@dots{} -@{ - int tem = foo (z); - next = min (x + y, tem); -@} -@end example - -@noindent -(where we assume that @samp{foo} returns type @samp{int}). - -@node Self-Reference, Argument Prescan, Side Effects, Macro Pitfalls -@subsubsection Self-Referential Macros - -@cindex self-reference -A @dfn{self-referential} macro is one whose name appears in its definition. -A special feature of ANSI Standard C is that the self-reference is not -considered a macro call. It is passed into the preprocessor output -unchanged. - -Let's consider an example: - -@example -#define foo (4 + foo) -@end example - -@noindent -where @samp{foo} is also a variable in your program. - -Following the ordinary rules, each reference to @samp{foo} will expand into -@samp{(4 + foo)}; then this will be rescanned and will expand into @samp{(4 -+ (4 + foo))}; and so on until it causes a fatal error (memory full) in the -preprocessor. - -However, the special rule about self-reference cuts this process short -after one step, at @samp{(4 + foo)}. Therefore, this macro definition -has the possibly useful effect of causing the program to add 4 to -the value of @samp{foo} wherever @samp{foo} is referred to. - -In most cases, it is a bad idea to take advantage of this feature. A -person reading the program who sees that @samp{foo} is a variable will -not expect that it is a macro as well. The reader will come across the -identifier @samp{foo} in the program and think its value should be that -of the variable @samp{foo}, whereas in fact the value is four greater. - -The special rule for self-reference applies also to @dfn{indirect} -self-reference. This is the case where a macro @var{x} expands to use a -macro @samp{y}, and the expansion of @samp{y} refers to the macro -@samp{x}. The resulting reference to @samp{x} comes indirectly from the -expansion of @samp{x}, so it is a self-reference and is not further -expanded. Thus, after - -@example -#define x (4 + y) -#define y (2 * x) -@end example - -@noindent -@samp{x} would expand into @samp{(4 + (2 * x))}. Clear? - -But suppose @samp{y} is used elsewhere, not from the definition of @samp{x}. -Then the use of @samp{x} in the expansion of @samp{y} is not a self-reference -because @samp{x} is not ``in progress''. So it does expand. However, -the expansion of @samp{x} contains a reference to @samp{y}, and that -is an indirect self-reference now because @samp{y} is ``in progress''. -The result is that @samp{y} expands to @samp{(2 * (4 + y))}. - -It is not clear that this behavior would ever be useful, but it is specified -by the ANSI C standard, so you may need to understand it. - -@node Argument Prescan, Cascaded Macros, Self-Reference, Macro Pitfalls -@subsubsection Separate Expansion of Macro Arguments -@cindex expansion of arguments -@cindex macro argument expansion -@cindex prescan of macro arguments - -We have explained that the expansion of a macro, including the substituted -actual arguments, is scanned over again for macro calls to be expanded. - -What really happens is more subtle: first each actual argument text is scanned -separately for macro calls. Then the results of this are substituted into -the macro body to produce the macro expansion, and the macro expansion -is scanned again for macros to expand. - -The result is that the actual arguments are scanned @emph{twice} to expand -macro calls in them. - -Most of the time, this has no effect. If the actual argument contained -any macro calls, they are expanded during the first scan. The result -therefore contains no macro calls, so the second scan does not change it. -If the actual argument were substituted as given, with no prescan, -the single remaining scan would find the same macro calls and produce -the same results. - -You might expect the double scan to change the results when a -self-referential macro is used in an actual argument of another macro -(@pxref{Self-Reference}): the self-referential macro would be expanded once -in the first scan, and a second time in the second scan. But this is not -what happens. The self-references that do not expand in the first scan are -marked so that they will not expand in the second scan either. - -The prescan is not done when an argument is stringified or concatenated. -Thus, - -@example -#define str(s) #s -#define foo 4 -str (foo) -@end example - -@noindent -expands to @samp{"foo"}. Once more, prescan has been prevented from -having any noticeable effect. - -More precisely, stringification and concatenation use the argument as -written, in un-prescanned form. The same actual argument would be used in -prescanned form if it is substituted elsewhere without stringification or -concatenation. - -@example -#define str(s) #s lose(s) -#define foo 4 -str (foo) -@end example - -expands to @samp{"foo" lose(4)}. - -You might now ask, ``Why mention the prescan, if it makes no difference? -And why not skip it and make the preprocessor faster?'' The answer is -that the prescan does make a difference in three special cases: - -@itemize @bullet -@item -Nested calls to a macro. - -@item -Macros that call other macros that stringify or concatenate. - -@item -Macros whose expansions contain unshielded commas. -@end itemize - -We say that @dfn{nested} calls to a macro occur when a macro's actual -argument contains a call to that very macro. For example, if @samp{f} -is a macro that expects one argument, @samp{f (f (1))} is a nested -pair of calls to @samp{f}. The desired expansion is made by -expanding @samp{f (1)} and substituting that into the definition of -@samp{f}. The prescan causes the expected result to happen. -Without the prescan, @samp{f (1)} itself would be substituted as -an actual argument, and the inner use of @samp{f} would appear -during the main scan as an indirect self-reference and would not -be expanded. Here, the prescan cancels an undesirable side effect -(in the medical, not computational, sense of the term) of the special -rule for self-referential macros. - -But prescan causes trouble in certain other cases of nested macro calls. -Here is an example: - -@example -#define foo a,b -#define bar(x) lose(x) -#define lose(x) (1 + (x)) - -bar(foo) -@end example - -@noindent -We would like @samp{bar(foo)} to turn into @samp{(1 + (foo))}, which -would then turn into @samp{(1 + (a,b))}. But instead, @samp{bar(foo)} -expands into @samp{lose(a,b)}, and you get an error because @code{lose} -requires a single argument. In this case, the problem is easily solved -by the same parentheses that ought to be used to prevent misnesting of -arithmetic operations: - -@example -#define foo (a,b) -#define bar(x) lose((x)) -@end example - -The problem is more serious when the operands of the macro are not -expressions; for example, when they are statements. Then parentheses -are unacceptable because they would make for invalid C code: - -@example -#define foo @{ int a, b; @dots{} @} -@end example - -@noindent -In GNU C you can shield the commas using the @samp{(@{@dots{}@})} -construct which turns a compound statement into an expression: - -@example -#define foo (@{ int a, b; @dots{} @}) -@end example - -Or you can rewrite the macro definition to avoid such commas: - -@example -#define foo @{ int a; int b; @dots{} @} -@end example - -There is also one case where prescan is useful. It is possible -to use prescan to expand an argument and then stringify it---if you use -two levels of macros. Let's add a new macro @samp{xstr} to the -example shown above: - -@example -#define xstr(s) str(s) -#define str(s) #s -#define foo 4 -xstr (foo) -@end example - -This expands into @samp{"4"}, not @samp{"foo"}. The reason for the -difference is that the argument of @samp{xstr} is expanded at prescan -(because @samp{xstr} does not specify stringification or concatenation of -the argument). The result of prescan then forms the actual argument for -@samp{str}. @samp{str} uses its argument without prescan because it -performs stringification; but it cannot prevent or undo the prescanning -already done by @samp{xstr}. - -@node Cascaded Macros, Newlines in Args, Argument Prescan, Macro Pitfalls -@subsubsection Cascaded Use of Macros - -@cindex cascaded macros -@cindex macro body uses macro -A @dfn{cascade} of macros is when one macro's body contains a reference -to another macro. This is very common practice. For example, - -@example -#define BUFSIZE 1020 -#define TABLESIZE BUFSIZE -@end example - -This is not at all the same as defining @samp{TABLESIZE} to be @samp{1020}. -The @samp{#define} for @samp{TABLESIZE} uses exactly the body you -specify---in this case, @samp{BUFSIZE}---and does not check to see whether -it too is the name of a macro. - -It's only when you @emph{use} @samp{TABLESIZE} that the result of its expansion -is checked for more macro names. - -This makes a difference if you change the definition of @samp{BUFSIZE} -at some point in the source file. @samp{TABLESIZE}, defined as shown, -will always expand using the definition of @samp{BUFSIZE} that is -currently in effect: - -@example -#define BUFSIZE 1020 -#define TABLESIZE BUFSIZE -#undef BUFSIZE -#define BUFSIZE 37 -@end example - -@noindent -Now @samp{TABLESIZE} expands (in two stages) to @samp{37}. (The -@samp{#undef} is to prevent any warning about the nontrivial -redefinition of @code{BUFSIZE}.) - -@node Newlines in Args,, Cascaded Macros, Macro Pitfalls -@subsection Newlines in Macro Arguments -@cindex newlines in macro arguments - -Traditional macro processing carries forward all newlines in macro -arguments into the expansion of the macro. This means that, if some of -the arguments are substituted more than once, or not at all, or out of -order, newlines can be duplicated, lost, or moved around within the -expansion. If the expansion consists of multiple statements, then the -effect is to distort the line numbers of some of these statements. The -result can be incorrect line numbers, in error messages or displayed in -a debugger. - -The GNU C preprocessor operating in ANSI C mode adjusts appropriately -for multiple use of an argument---the first use expands all the -newlines, and subsequent uses of the same argument produce no newlines. -But even in this mode, it can produce incorrect line numbering if -arguments are used out of order, or not used at all. - -Here is an example illustrating this problem: - -@example -#define ignore_second_arg(a,b,c) a; c - -ignore_second_arg (foo (), - ignored (), - syntax error); -@end example - -@noindent -The syntax error triggered by the tokens @samp{syntax error} results -in an error message citing line four, even though the statement text -comes from line five. - -@node Conditionals, Combining Sources, Macros, Top -@section Conditionals - -@cindex conditionals -In a macro processor, a @dfn{conditional} is a directive that allows a part -of the program to be ignored during compilation, on some conditions. -In the C preprocessor, a conditional can test either an arithmetic expression -or whether a name is defined as a macro. - -A conditional in the C preprocessor resembles in some ways an @samp{if} -statement in C, but it is important to understand the difference between -them. The condition in an @samp{if} statement is tested during the execution -of your program. Its purpose is to allow your program to behave differently -from run to run, depending on the data it is operating on. The condition -in a preprocessing conditional directive is tested when your program is compiled. -Its purpose is to allow different code to be included in the program depending -on the situation at the time of compilation. - -@menu -* Uses: Conditional Uses. What conditionals are for. -* Syntax: Conditional Syntax. How conditionals are written. -* Deletion: Deleted Code. Making code into a comment. -* Macros: Conditionals-Macros. Why conditionals are used with macros. -* Assertions:: How and why to use assertions. -* Errors: #error Directive. Detecting inconsistent compilation parameters. -@end menu - -@node Conditional Uses -@subsection Why Conditionals are Used - -Generally there are three kinds of reason to use a conditional. - -@itemize @bullet -@item -A program may need to use different code depending on the machine or -operating system it is to run on. In some cases the code for one -operating system may be erroneous on another operating system; for -example, it might refer to library routines that do not exist on the -other system. When this happens, it is not enough to avoid executing -the invalid code: merely having it in the program makes it impossible -to link the program and run it. With a preprocessing conditional, the -offending code can be effectively excised from the program when it is -not valid. - -@item -You may want to be able to compile the same source file into two -different programs. Sometimes the difference between the programs is -that one makes frequent time-consuming consistency checks on its -intermediate data, or prints the values of those data for debugging, -while the other does not. - -@item -A conditional whose condition is always false is a good way to exclude -code from the program but keep it as a sort of comment for future -reference. -@end itemize - -Most simple programs that are intended to run on only one machine will -not need to use preprocessing conditionals. - -@node Conditional Syntax -@subsection Syntax of Conditionals - -@findex #if -A conditional in the C preprocessor begins with a @dfn{conditional -directive}: @samp{#if}, @samp{#ifdef} or @samp{#ifndef}. -@xref{Conditionals-Macros}, for information on @samp{#ifdef} and -@samp{#ifndef}; only @samp{#if} is explained here. - -@menu -* If: #if Directive. Basic conditionals using @samp{#if} and @samp{#endif}. -* Else: #else Directive. Including some text if the condition fails. -* Elif: #elif Directive. Testing several alternative possibilities. -@end menu - -@node #if Directive -@subsubsection The @samp{#if} Directive - -The @samp{#if} directive in its simplest form consists of - -@example -#if @var{expression} -@var{controlled text} -#endif /* @var{expression} */ -@end example - -The comment following the @samp{#endif} is not required, but it is a good -practice because it helps people match the @samp{#endif} to the -corresponding @samp{#if}. Such comments should always be used, except in -short conditionals that are not nested. In fact, you can put anything at -all after the @samp{#endif} and it will be ignored by the GNU C preprocessor, -but only comments are acceptable in ANSI Standard C. - -@var{expression} is a C expression of integer type, subject to stringent -restrictions. It may contain - -@itemize @bullet -@item -Integer constants, which are all regarded as @code{long} or -@code{unsigned long}. - -@item -Character constants, which are interpreted according to the character -set and conventions of the machine and operating system on which the -preprocessor is running. The GNU C preprocessor uses the C data type -@samp{char} for these character constants; therefore, whether some -character codes are negative is determined by the C compiler used to -compile the preprocessor. If it treats @samp{char} as signed, then -character codes large enough to set the sign bit will be considered -negative; otherwise, no character code is considered negative. - -@item -Arithmetic operators for addition, subtraction, multiplication, -division, bitwise operations, shifts, comparisons, and logical -operations (@samp{&&} and @samp{||}). - -@item -Identifiers that are not macros, which are all treated as zero(!). - -@item -Macro calls. All macro calls in the expression are expanded before -actual computation of the expression's value begins. -@end itemize - -Note that @samp{sizeof} operators and @code{enum}-type values are not allowed. -@code{enum}-type values, like all other identifiers that are not taken -as macro calls and expanded, are treated as zero. - -The @var{controlled text} inside of a conditional can include -preprocessing directives. Then the directives inside the conditional are -obeyed only if that branch of the conditional succeeds. The text can -also contain other conditional groups. However, the @samp{#if} and -@samp{#endif} directives must balance. - -@node #else Directive -@subsubsection The @samp{#else} Directive - -@findex #else -The @samp{#else} directive can be added to a conditional to provide -alternative text to be used if the condition is false. This is what -it looks like: - -@example -#if @var{expression} -@var{text-if-true} -#else /* Not @var{expression} */ -@var{text-if-false} -#endif /* Not @var{expression} */ -@end example - -If @var{expression} is nonzero, and thus the @var{text-if-true} is -active, then @samp{#else} acts like a failing conditional and the -@var{text-if-false} is ignored. Contrariwise, if the @samp{#if} -conditional fails, the @var{text-if-false} is considered included. - -@node #elif Directive -@subsubsection The @samp{#elif} Directive - -@findex #elif -One common case of nested conditionals is used to check for more than two -possible alternatives. For example, you might have - -@example -#if X == 1 -@dots{} -#else /* X != 1 */ -#if X == 2 -@dots{} -#else /* X != 2 */ -@dots{} -#endif /* X != 2 */ -#endif /* X != 1 */ -@end example - -Another conditional directive, @samp{#elif}, allows this to be abbreviated -as follows: - -@example -#if X == 1 -@dots{} -#elif X == 2 -@dots{} -#else /* X != 2 and X != 1*/ -@dots{} -#endif /* X != 2 and X != 1*/ -@end example - -@samp{#elif} stands for ``else if''. Like @samp{#else}, it goes in the -middle of a @samp{#if}-@samp{#endif} pair and subdivides it; it does not -require a matching @samp{#endif} of its own. Like @samp{#if}, the -@samp{#elif} directive includes an expression to be tested. - -The text following the @samp{#elif} is processed only if the original -@samp{#if}-condition failed and the @samp{#elif} condition succeeds. -More than one @samp{#elif} can go in the same @samp{#if}-@samp{#endif} -group. Then the text after each @samp{#elif} is processed only if the -@samp{#elif} condition succeeds after the original @samp{#if} and any -previous @samp{#elif} directives within it have failed. @samp{#else} is -equivalent to @samp{#elif 1}, and @samp{#else} is allowed after any -number of @samp{#elif} directives, but @samp{#elif} may not follow -@samp{#else}. - -@node Deleted Code -@subsection Keeping Deleted Code for Future Reference -@cindex commenting out code - -If you replace or delete a part of the program but want to keep the old -code around as a comment for future reference, the easy way to do this -is to put @samp{#if 0} before it and @samp{#endif} after it. This is -better than using comment delimiters @samp{/*} and @samp{*/} since those -won't work if the code already contains comments (C comments do not -nest). - -This works even if the code being turned off contains conditionals, but -they must be entire conditionals (balanced @samp{#if} and @samp{#endif}). - -Conversely, do not use @samp{#if 0} for comments which are not C code. -Use the comment delimiters @samp{/*} and @samp{*/} instead. The -interior of @samp{#if 0} must consist of complete tokens; in particular, -singlequote characters must balance. But comments often contain -unbalanced singlequote characters (known in English as apostrophes). -These confuse @samp{#if 0}. They do not confuse @samp{/*}. - -@node Conditionals-Macros -@subsection Conditionals and Macros - -Conditionals are useful in connection with macros or assertions, because -those are the only ways that an expression's value can vary from one -compilation to another. A @samp{#if} directive whose expression uses no -macros or assertions is equivalent to @samp{#if 1} or @samp{#if 0}; you -might as well determine which one, by computing the value of the -expression yourself, and then simplify the program. - -For example, here is a conditional that tests the expression -@samp{BUFSIZE == 1020}, where @samp{BUFSIZE} must be a macro. - -@example -#if BUFSIZE == 1020 - printf ("Large buffers!\n"); -#endif /* BUFSIZE is large */ -@end example - -(Programmers often wish they could test the size of a variable or data -type in @samp{#if}, but this does not work. The preprocessor does not -understand @code{sizeof}, or typedef names, or even the type keywords -such as @code{int}.) - -@findex defined -The special operator @samp{defined} is used in @samp{#if} expressions to -test whether a certain name is defined as a macro. Either @samp{defined -@var{name}} or @samp{defined (@var{name})} is an expression whose value -is 1 if @var{name} is defined as macro at the current point in the -program, and 0 otherwise. For the @samp{defined} operator it makes no -difference what the definition of the macro is; all that matters is -whether there is a definition. Thus, for example,@refill - -@example -#if defined (vax) || defined (ns16000) -@end example - -@noindent -would succeed if either of the names @samp{vax} and @samp{ns16000} is -defined as a macro. You can test the same condition using assertions -(@pxref{Assertions}), like this: - -@example -#if #cpu (vax) || #cpu (ns16000) -@end example - -If a macro is defined and later undefined with @samp{#undef}, -subsequent use of the @samp{defined} operator returns 0, because -the name is no longer defined. If the macro is defined again with -another @samp{#define}, @samp{defined} will recommence returning 1. - -@findex #ifdef -@findex #ifndef -Conditionals that test whether just one name is defined are very common, -so there are two special short conditional directives for this case. - -@table @code -@item #ifdef @var{name} -is equivalent to @samp{#if defined (@var{name})}. - -@item #ifndef @var{name} -is equivalent to @samp{#if ! defined (@var{name})}. -@end table - -Macro definitions can vary between compilations for several reasons. - -@itemize @bullet -@item -Some macros are predefined on each kind of machine. For example, on a -Vax, the name @samp{vax} is a predefined macro. On other machines, it -would not be defined. - -@item -Many more macros are defined by system header files. Different -systems and machines define different macros, or give them different -values. It is useful to test these macros with conditionals to avoid -using a system feature on a machine where it is not implemented. - -@item -Macros are a common way of allowing users to customize a program for -different machines or applications. For example, the macro -@samp{BUFSIZE} might be defined in a configuration file for your -program that is included as a header file in each source file. You -would use @samp{BUFSIZE} in a preprocessing conditional in order to -generate different code depending on the chosen configuration. - -@item -Macros can be defined or undefined with @samp{-D} and @samp{-U} -command options when you compile the program. You can arrange to -compile the same source file into two different programs by choosing -a macro name to specify which program you want, writing conditionals -to test whether or how this macro is defined, and then controlling -the state of the macro with compiler command options. -@xref{Invocation}. -@end itemize - -@ifinfo -Assertions are usually predefined, but can be defined with preprocessor -directives or command-line options. -@end ifinfo - -@node Assertions -@subsection Assertions - -@cindex assertions -@dfn{Assertions} are a more systematic alternative to macros in writing -conditionals to test what sort of computer or system the compiled -program will run on. Assertions are usually predefined, but you can -define them with preprocessing directives or command-line options. - -@cindex predicates -The macros traditionally used to describe the type of target are not -classified in any way according to which question they answer; they may -indicate a hardware architecture, a particular hardware model, an -operating system, a particular version of an operating system, or -specific configuration options. These are jumbled together in a single -namespace. In contrast, each assertion consists of a named question and -an answer. The question is usually called the @dfn{predicate}. -An assertion looks like this: - -@example -#@var{predicate} (@var{answer}) -@end example - -@noindent -You must use a properly formed identifier for @var{predicate}. The -value of @var{answer} can be any sequence of words; all characters are -significant except for leading and trailing whitespace, and differences -in internal whitespace sequences are ignored. Thus, @samp{x + y} is -different from @samp{x+y} but equivalent to @samp{x + y}. @samp{)} is -not allowed in an answer. - -@cindex testing predicates -Here is a conditional to test whether the answer @var{answer} is asserted -for the predicate @var{predicate}: - -@example -#if #@var{predicate} (@var{answer}) -@end example - -@noindent -There may be more than one answer asserted for a given predicate. If -you omit the answer, you can test whether @emph{any} answer is asserted -for @var{predicate}: - -@example -#if #@var{predicate} -@end example - -@findex #system -@findex #machine -@findex #cpu -Most of the time, the assertions you test will be predefined assertions. -GNU C provides three predefined predicates: @code{system}, @code{cpu}, -and @code{machine}. @code{system} is for assertions about the type of -software, @code{cpu} describes the type of computer architecture, and -@code{machine} gives more information about the computer. For example, -on a GNU system, the following assertions would be true: - -@example -#system (gnu) -#system (mach) -#system (mach 3) -#system (mach 3.@var{subversion}) -#system (hurd) -#system (hurd @var{version}) -@end example - -@noindent -and perhaps others. The alternatives with -more or less version information let you ask more or less detailed -questions about the type of system software. - -On a Unix system, you would find @code{#system (unix)} and perhaps one of: -@code{#system (aix)}, @code{#system (bsd)}, @code{#system (hpux)}, -@code{#system (lynx)}, @code{#system (mach)}, @code{#system (posix)}, -@code{#system (svr3)}, @code{#system (svr4)}, or @code{#system (xpg4)} -with possible version numbers following. - -Other values for @code{system} are @code{#system (mvs)} -and @code{#system (vms)}. - -@strong{Portability note:} Many Unix C compilers provide only one answer -for the @code{system} assertion: @code{#system (unix)}, if they support -assertions at all. This is less than useful. - -An assertion with a multi-word answer is completely different from several -assertions with individual single-word answers. For example, the presence -of @code{system (mach 3.0)} does not mean that @code{system (3.0)} is true. -It also does not directly imply @code{system (mach)}, but in GNU C, that -last will normally be asserted as well. - -The current list of possible assertion values for @code{cpu} is: -@code{#cpu (a29k)}, @code{#cpu (alpha)}, @code{#cpu (arm)}, @code{#cpu -(clipper)}, @code{#cpu (convex)}, @code{#cpu (elxsi)}, @code{#cpu -(tron)}, @code{#cpu (h8300)}, @code{#cpu (i370)}, @code{#cpu (i386)}, -@code{#cpu (i860)}, @code{#cpu (i960)}, @code{#cpu (m68k)}, @code{#cpu -(m88k)}, @code{#cpu (mips)}, @code{#cpu (ns32k)}, @code{#cpu (hppa)}, -@code{#cpu (pyr)}, @code{#cpu (ibm032)}, @code{#cpu (rs6000)}, -@code{#cpu (sh)}, @code{#cpu (sparc)}, @code{#cpu (spur)}, @code{#cpu -(tahoe)}, @code{#cpu (vax)}, @code{#cpu (we32000)}. - -@findex #assert -You can create assertions within a C program using @samp{#assert}, like -this: - -@example -#assert @var{predicate} (@var{answer}) -@end example - -@noindent -(Note the absence of a @samp{#} before @var{predicate}.) - -@cindex unassert -@cindex assertions, undoing -@cindex retracting assertions -@findex #unassert -Each time you do this, you assert a new true answer for @var{predicate}. -Asserting one answer does not invalidate previously asserted answers; -they all remain true. The only way to remove an assertion is with -@samp{#unassert}. @samp{#unassert} has the same syntax as -@samp{#assert}. You can also remove all assertions about -@var{predicate} like this: - -@example -#unassert @var{predicate} -@end example - -You can also add or cancel assertions using command options -when you run @code{gcc} or @code{cpp}. @xref{Invocation}. - -@node #error Directive -@subsection The @samp{#error} and @samp{#warning} Directives - -@findex #error -The directive @samp{#error} causes the preprocessor to report a fatal -error. The rest of the line that follows @samp{#error} is used as the -error message. - -You would use @samp{#error} inside of a conditional that detects a -combination of parameters which you know the program does not properly -support. For example, if you know that the program will not run -properly on a Vax, you might write - -@smallexample -@group -#ifdef __vax__ -#error Won't work on Vaxen. See comments at get_last_object. -#endif -@end group -@end smallexample - -@noindent -@xref{Nonstandard Predefined}, for why this works. - -If you have several configuration parameters that must be set up by -the installation in a consistent way, you can use conditionals to detect -an inconsistency and report it with @samp{#error}. For example, - -@smallexample -#if HASH_TABLE_SIZE % 2 == 0 || HASH_TABLE_SIZE % 3 == 0 \ - || HASH_TABLE_SIZE % 5 == 0 -#error HASH_TABLE_SIZE should not be divisible by a small prime -#endif -@end smallexample - -@findex #warning -The directive @samp{#warning} is like the directive @samp{#error}, but causes -the preprocessor to issue a warning and continue preprocessing. The rest of -the line that follows @samp{#warning} is used as the warning message. - -You might use @samp{#warning} in obsolete header files, with a message -directing the user to the header file which should be used instead. - -@node Combining Sources, Other Directives, Conditionals, Top -@section Combining Source Files - -@cindex line control -One of the jobs of the C preprocessor is to inform the C compiler of where -each line of C code came from: which source file and which line number. - -C code can come from multiple source files if you use @samp{#include}; -both @samp{#include} and the use of conditionals and macros can cause -the line number of a line in the preprocessor output to be different -from the line's number in the original source file. You will appreciate -the value of making both the C compiler (in error messages) and symbolic -debuggers such as GDB use the line numbers in your source file. - -The C preprocessor builds on this feature by offering a directive by which -you can control the feature explicitly. This is useful when a file for -input to the C preprocessor is the output from another program such as the -@code{bison} parser generator, which operates on another file that is the -true source file. Parts of the output from @code{bison} are generated from -scratch, other parts come from a standard parser file. The rest are copied -nearly verbatim from the source file, but their line numbers in the -@code{bison} output are not the same as their original line numbers. -Naturally you would like compiler error messages and symbolic debuggers to -know the original source file and line number of each line in the -@code{bison} input. - -@findex #line -@code{bison} arranges this by writing @samp{#line} directives into the output -file. @samp{#line} is a directive that specifies the original line number -and source file name for subsequent input in the current preprocessor input -file. @samp{#line} has three variants: - -@table @code -@item #line @var{linenum} -Here @var{linenum} is a decimal integer constant. This specifies that -the line number of the following line of input, in its original source file, -was @var{linenum}. - -@item #line @var{linenum} @var{filename} -Here @var{linenum} is a decimal integer constant and @var{filename} -is a string constant. This specifies that the following line of input -came originally from source file @var{filename} and its line number there -was @var{linenum}. Keep in mind that @var{filename} is not just a -file name; it is surrounded by doublequote characters so that it looks -like a string constant. - -@item #line @var{anything else} -@var{anything else} is checked for macro calls, which are expanded. -The result should be a decimal integer constant followed optionally -by a string constant, as described above. -@end table - -@samp{#line} directives alter the results of the @samp{__FILE__} and -@samp{__LINE__} predefined macros from that point on. @xref{Standard -Predefined}. - -The output of the preprocessor (which is the input for the rest of the -compiler) contains directives that look much like @samp{#line} directives. -They start with just @samp{#} instead of @samp{#line}, but this is -followed by a line number and file name as in @samp{#line}. @xref{Output}. - -@node Other Directives, Output, Combining Sources, Top -@section Miscellaneous Preprocessing Directives - -@cindex null directive -This section describes three additional preprocessing directives. They are -not very useful, but are mentioned for completeness. - -The @dfn{null directive} consists of a @samp{#} followed by a Newline, with -only whitespace (including comments) in between. A null directive is -understood as a preprocessing directive but has no effect on the preprocessor -output. The primary significance of the existence of the null directive is -that an input line consisting of just a @samp{#} will produce no output, -rather than a line of output containing just a @samp{#}. Supposedly -some old C programs contain such lines. - -@findex #pragma -The ANSI standard specifies that the @samp{#pragma} directive has an -arbitrary, implementation-defined effect. In the GNU C preprocessor, -@samp{#pragma} directives are not used, except for @samp{#pragma once} -(@pxref{Once-Only}). However, they are left in the preprocessor output, -so they are available to the compilation pass. - -@findex #ident -The @samp{#ident} directive is supported for compatibility with certain -other systems. It is followed by a line of text. On some systems, the -text is copied into a special place in the object file; on most systems, -the text is ignored and this directive has no effect. Typically -@samp{#ident} is only used in header files supplied with those systems -where it is meaningful. - -@node Output, Invocation, Other Directives, Top -@section C Preprocessor Output - -@cindex output format -The output from the C preprocessor looks much like the input, except -that all preprocessing directive lines have been replaced with blank lines -and all comments with spaces. Whitespace within a line is not altered; -however, a space is inserted after the expansions of most macro calls. - -Source file name and line number information is conveyed by lines of -the form - -@example -# @var{linenum} @var{filename} @var{flags} -@end example - -@noindent -which are inserted as needed into the middle of the input (but never -within a string or character constant). Such a line means that the -following line originated in file @var{filename} at line @var{linenum}. - -After the file name comes zero or more flags, which are @samp{1}, -@samp{2}, @samp{3}, or @samp{4}. If there are multiple flags, spaces separate -them. Here is what the flags mean: - -@table @samp -@item 1 -This indicates the start of a new file. -@item 2 -This indicates returning to a file (after having included another file). -@item 3 -This indicates that the following text comes from a system header file, -so certain warnings should be suppressed. -@item 4 -This indicates that the following text should be treated as C. -@c maybe cross reference NO_IMPLICIT_EXTERN_C -@end table - -@node Invocation, Concept Index, Output, Top -@section Invoking the C Preprocessor -@cindex invocation of the preprocessor - -Most often when you use the C preprocessor you will not have to invoke it -explicitly: the C compiler will do so automatically. However, the -preprocessor is sometimes useful on its own. - -The C preprocessor expects two file names as arguments, @var{infile} and -@var{outfile}. The preprocessor reads @var{infile} together with any other -files it specifies with @samp{#include}. All the output generated by the -combined input files is written in @var{outfile}. - -Either @var{infile} or @var{outfile} may be @samp{-}, which as @var{infile} -means to read from standard input and as @var{outfile} means to write to -standard output. Also, if @var{outfile} or both file names are omitted, -the standard output and standard input are used for the omitted file names. - -@cindex options -Here is a table of command options accepted by the C preprocessor. -These options can also be given when compiling a C program; they are -passed along automatically to the preprocessor when it is invoked by the -compiler. - -@table @samp -@item -P -@findex -P -Inhibit generation of @samp{#}-lines with line-number information in -the output from the preprocessor (@pxref{Output}). This might be -useful when running the preprocessor on something that is not C code -and will be sent to a program which might be confused by the -@samp{#}-lines. - -@item -C -@findex -C -Do not discard comments: pass them through to the output file. -Comments appearing in arguments of a macro call will be copied to the -output before the expansion of the macro call. - -@item -traditional -@findex -traditional -Try to imitate the behavior of old-fashioned C, as opposed to ANSI C. - -@itemize @bullet -@item -Traditional macro expansion pays no attention to singlequote or -doublequote characters; macro argument symbols are replaced by the -argument values even when they appear within apparent string or -character constants. - -@item -Traditionally, it is permissible for a macro expansion to end in the -middle of a string or character constant. The constant continues into -the text surrounding the macro call. - -@item -However, traditionally the end of the line terminates a string or -character constant, with no error. - -@item -In traditional C, a comment is equivalent to no text at all. (In ANSI -C, a comment counts as whitespace.) - -@item -Traditional C does not have the concept of a ``preprocessing number''. -It considers @samp{1.0e+4} to be three tokens: @samp{1.0e}, @samp{+}, -and @samp{4}. - -@item -A macro is not suppressed within its own definition, in traditional C. -Thus, any macro that is used recursively inevitably causes an error. - -@item -The character @samp{#} has no special meaning within a macro definition -in traditional C. - -@item -In traditional C, the text at the end of a macro expansion can run -together with the text after the macro call, to produce a single token. -(This is impossible in ANSI C.) - -@item -Traditionally, @samp{\} inside a macro argument suppresses the syntactic -significance of the following character. -@end itemize - -@item -trigraphs -@findex -trigraphs -Process ANSI standard trigraph sequences. These are three-character -sequences, all starting with @samp{??}, that are defined by ANSI C to -stand for single characters. For example, @samp{??/} stands for -@samp{\}, so @samp{'??/n'} is a character constant for a newline. -Strictly speaking, the GNU C preprocessor does not support all -programs in ANSI Standard C unless @samp{-trigraphs} is used, but if -you ever notice the difference it will be with relief. - -You don't want to know any more about trigraphs. - -@item -pedantic -@findex -pedantic -Issue warnings required by the ANSI C standard in certain cases such -as when text other than a comment follows @samp{#else} or @samp{#endif}. - -@item -pedantic-errors -@findex -pedantic-errors -Like @samp{-pedantic}, except that errors are produced rather than -warnings. - -@item -Wtrigraphs -@findex -Wtrigraphs -Warn if any trigraphs are encountered (assuming they are enabled). - -@item -Wcomment -@findex -Wcomment -@ignore -@c "Not worth documenting" both singular and plural forms of this -@c option, per RMS. But also unclear which is better; hence may need to -@c switch this at some future date. pesch@cygnus.com, 2jan92. -@itemx -Wcomments -(Both forms have the same effect). -@end ignore -Warn whenever a comment-start sequence @samp{/*} appears in a comment. - -@item -Wall -@findex -Wall -Requests both @samp{-Wtrigraphs} and @samp{-Wcomment} (but not -@samp{-Wtraditional}). - -@item -Wtraditional -@findex -Wtraditional -Warn about certain constructs that behave differently in traditional and -ANSI C. - -@item -I @var{directory} -@findex -I -Add the directory @var{directory} to the head of the list of -directories to be searched for header files (@pxref{Include Syntax}). -This can be used to override a system header file, substituting your -own version, since these directories are searched before the system -header file directories. If you use more than one @samp{-I} option, -the directories are scanned in left-to-right order; the standard -system directories come after. - -@item -I- -Any directories specified with @samp{-I} options before the @samp{-I-} -option are searched only for the case of @samp{#include "@var{file}"}; -they are not searched for @samp{#include <@var{file}>}. - -If additional directories are specified with @samp{-I} options after -the @samp{-I-}, these directories are searched for all @samp{#include} -directives. - -In addition, the @samp{-I-} option inhibits the use of the current -directory as the first search directory for @samp{#include "@var{file}"}. -Therefore, the current directory is searched only if it is requested -explicitly with @samp{-I.}. Specifying both @samp{-I-} and @samp{-I.} -allows you to control precisely which directories are searched before -the current one and which are searched after. - -@item -nostdinc -@findex -nostdinc -Do not search the standard system directories for header files. -Only the directories you have specified with @samp{-I} options -(and the current directory, if appropriate) are searched. - -@item -nostdinc++ -@findex -nostdinc++ -Do not search for header files in the C++-specific standard directories, -but do still search the other standard directories. -(This option is used when building libg++.) - -@item -D @var{name} -@findex -D -Predefine @var{name} as a macro, with definition @samp{1}. - -@item -D @var{name}=@var{definition} -Predefine @var{name} as a macro, with definition @var{definition}. -There are no restrictions on the contents of @var{definition}, but if -you are invoking the preprocessor from a shell or shell-like program you -may need to use the shell's quoting syntax to protect characters such as -spaces that have a meaning in the shell syntax. If you use more than -one @samp{-D} for the same @var{name}, the rightmost definition takes -effect. - -@item -U @var{name} -@findex -U -Do not predefine @var{name}. If both @samp{-U} and @samp{-D} are -specified for one name, the @samp{-U} beats the @samp{-D} and the name -is not predefined. - -@item -undef -@findex -undef -Do not predefine any nonstandard macros. - -@item -A @var{predicate}(@var{answer}) -@findex -A -Make an assertion with the predicate @var{predicate} and answer -@var{answer}. @xref{Assertions}. - -@noindent -You can use @samp{-A-} to disable all predefined assertions; it also -undefines all predefined macros that identify the type of target system. - -@item -dM -@findex -dM -Instead of outputting the result of preprocessing, output a list of -@samp{#define} directives for all the macros defined during the -execution of the preprocessor, including predefined macros. This gives -you a way of finding out what is predefined in your version of the -preprocessor; assuming you have no file @samp{foo.h}, the command - -@example -touch foo.h; cpp -dM foo.h -@end example - -@noindent -will show the values of any predefined macros. - -@item -dD -@findex -dD -Like @samp{-dM} except in two respects: it does @emph{not} include the -predefined macros, and it outputs @emph{both} the @samp{#define} -directives and the result of preprocessing. Both kinds of output go to -the standard output file. - -@item -M [-MG] -@findex -M -Instead of outputting the result of preprocessing, output a rule -suitable for @code{make} describing the dependencies of the main -source file. The preprocessor outputs one @code{make} rule containing -the object file name for that source file, a colon, and the names of -all the included files. If there are many included files then the -rule is split into several lines using @samp{\}-newline. - -@samp{-MG} says to treat missing header files as generated files and assume -they live in the same directory as the source file. It must be specified -in addition to @samp{-M}. - -This feature is used in automatic updating of makefiles. - -@item -MM [-MG] -@findex -MM -Like @samp{-M} but mention only the files included with @samp{#include -"@var{file}"}. System header files included with @samp{#include -<@var{file}>} are omitted. - -@item -MD @var{file} -@findex -MD -Like @samp{-M} but the dependency information is written to @var{file}. -This is in addition to compiling the file as specified---@samp{-MD} does -not inhibit ordinary compilation the way @samp{-M} does. - -When invoking gcc, do not specify the @var{file} argument. -Gcc will create file names made by replacing ".c" with ".d" at -the end of the input file names. - -In Mach, you can use the utility @code{md} to merge multiple dependency -files into a single dependency file suitable for using with the @samp{make} -command. - -@item -MMD @var{file} -@findex -MMD -Like @samp{-MD} except mention only user header files, not system -header files. - -@item -H -@findex -H -Print the name of each header file used, in addition to other normal -activities. - -@item -imacros @var{file} -@findex -imacros -Process @var{file} as input, discarding the resulting output, before -processing the regular input file. Because the output generated from -@var{file} is discarded, the only effect of @samp{-imacros @var{file}} -is to make the macros defined in @var{file} available for use in the -main input. - -@item -include @var{file} -@findex -include -Process @var{file} as input, and include all the resulting output, -before processing the regular input file. - -@item -idirafter @var{dir} -@findex -idirafter -@cindex second include path -Add the directory @var{dir} to the second include path. The directories -on the second include path are searched when a header file is not found -in any of the directories in the main include path (the one that -@samp{-I} adds to). - -@item -iprefix @var{prefix} -@findex -iprefix -Specify @var{prefix} as the prefix for subsequent @samp{-iwithprefix} -options. - -@item -iwithprefix @var{dir} -@findex -iwithprefix -Add a directory to the second include path. The directory's name is -made by concatenating @var{prefix} and @var{dir}, where @var{prefix} -was specified previously with @samp{-iprefix}. - -@item -isystem @var{dir} -@findex -isystem -Add a directory to the beginning of the second include path, marking it -as a system directory, so that it gets the same special treatment as -is applied to the standard system directories. - -@item -lang-c -@itemx -lang-c89 -@itemx -lang-c++ -@itemx -lang-objc -@itemx -lang-objc++ -@findex -lang-c -@findex -lang-c89 -@findex -lang-c++ -@findex -lang-objc -@findex -lang-objc++ -Specify the source language. @samp{-lang-c} is the default; it -allows recognition of C++ comments (comments that begin with -@samp{//} and end at end of line), since this is -a common feature and it will most likely be in the next C standard. -@samp{-lang-c89} disables recognition of C++ comments. @samp{-lang-c++} -handles C++ comment syntax and includes extra default include -directories for C++. @samp{-lang-objc} enables the Objective C -@samp{#import} directive. @samp{-lang-objc++} enables both C++ and Objective C -extensions. - -These options are generated by the compiler driver @code{gcc}, but not -passed from the @samp{gcc} command line unless you use the driver's -@samp{-Wp} option. - -@item -lint -Look for commands to the program checker @code{lint} embedded in -comments, and emit them preceded by @samp{#pragma lint}. For example, -the comment @samp{/* NOTREACHED */} becomes @samp{#pragma lint -NOTREACHED}. - -This option is available only when you call @code{cpp} directly; -@code{gcc} will not pass it from its command line. - -@item -$ -@findex -$ -Forbid the use of @samp{$} in identifiers. This is required for ANSI -conformance. @code{gcc} automatically supplies this option to the -preprocessor if you specify @samp{-ansi}, but @code{gcc} doesn't -recognize the @samp{-$} option itself---to use it without the other -effects of @samp{-ansi}, you must call the preprocessor directly. - -@end table - -@node Concept Index, Index, Invocation, Top -@unnumbered Concept Index -@printindex cp - -@node Index,, Concept Index, Top -@unnumbered Index of Directives, Macros and Options -@printindex fn - -@contents -@bye diff --git a/support/cpp/cppalloc.c b/support/cpp/cppalloc.c deleted file mode 100644 index 23cd61f5..00000000 --- a/support/cpp/cppalloc.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Part of CPP library. (memory allocation - xmalloc etc) - Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. - Written by Per Bothner, 1994. - Based on CCCP program by by Paul Rubin, June 1986 - Adapted to ANSI C, Richard Stallman, Jan 1987 - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! */ - -// #include "config.h" -// #ifdef HAVE_MALLOC_H -// #include -// #endif -// -// static void -// memory_full () -// { -// perror ("Memory exhausted."); -//} -// -// char *xmalloc ( unsigned size) -// { -// register char *ptr = (char *) malloc (size); -// if (ptr != 0) return (ptr); -// memory_full (); - /*NOTREACHED*/ -// return 0; -// } -// -// char *xrealloc ( -// char *old, -// unsigned size ) -// { -// register char *ptr = (char *) realloc (old, size); -// if (ptr == 0) -// memory_full (); -// return ptr; -// } -// -// char *xcalloc ( -// unsigned number, unsigned size) -// { -// register unsigned total = number * size; -// register char *ptr = (char *) calloc (number, size); -// if (ptr == 0) -// memory_full (); -// return ptr; -// } diff --git a/support/cpp/cpperror.c b/support/cpp/cpperror.c deleted file mode 100644 index 088d11eb..00000000 --- a/support/cpp/cpperror.c +++ /dev/null @@ -1,132 +0,0 @@ -/* Default error handlers for CPP Library. - Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. - Written by Per Bothner, 1994. - Based on CCCP program by by Paul Rubin, June 1986 - Adapted to ANSI C, Richard Stallman, Jan 1987 - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! */ - -#define EMACS -#define FATAL_EXIT_CODE 33 -#ifndef EMACS -#include "config.h" -#endif /* not EMACS */ - -#include "cpplib.h" -#include -#include - -/* Print the file names and line numbers of the #include - commands which led to the current file. */ - -void -cpp_print_containing_files ( - cpp_reader *pfile) -{ - cpp_buffer *ip; - int first = 1; - - /* If stack of files hasn't changed since we last printed - this info, don't repeat it. */ - if (pfile->input_stack_listing_current) - return; - - ip = cpp_file_buffer (pfile); - - /* Give up if we don't find a source file. */ - if (ip == NULL) - return; - - /* Find the other, outer source files. */ - while ((ip = CPP_PREV_BUFFER (ip)), ip != CPP_NULL_BUFFER (pfile)) - { - long line, col; - cpp_buf_line_and_col (ip, &line, &col); - if (ip->fname != NULL) - { - if (first) - { - first = 0; - fprintf (stderr, "In file included"); - } - else - fprintf (stderr, ",\n "); - } - - fprintf (stderr, " from %s:%ld", ip->nominal_fname, line); - } - if (! first) - fprintf (stderr, ":\n"); - - /* Record we have printed the status as of this time. */ - pfile->input_stack_listing_current = 1; -} - -void -cpp_file_line_for_message ( - cpp_reader *pfile, - char *filename , - int line, int column) -{ - if (column > 0) - fprintf (stderr, "%s:%d:%d: ", filename, line, column); - else - fprintf (stderr, "%s:%d: ", filename, line); -} - -/* IS_ERROR is 1 for error, 0 for warning */ -void cpp_message ( - cpp_reader *pfile, - int is_error, - char *msg, - char *arg1, char *arg2, char *arg3) -{ - if (is_error) { - pfile->errors++; - fprintf (stderr,"error:"); - } - else { - fprintf (stderr, "warning: "); - } - fprintf (stderr, msg, arg1, arg2, arg3); - fprintf (stderr, "\n"); -} - -void -fatal (char *str,char *arg) -{ - fprintf (stderr, "%s: ", progname); - fprintf (stderr, str, arg); - fprintf (stderr, "\n"); - exit (FATAL_EXIT_CODE); -} - - -void -cpp_pfatal_with_name ( - cpp_reader *pfile, - char *name) -{ - cpp_perror_with_name (pfile, name); -#ifdef VMS - exit (vaxc$errno); -#else - exit (FATAL_EXIT_CODE); -#endif -} diff --git a/support/cpp/cppexp.c b/support/cpp/cppexp.c deleted file mode 100644 index 2bc875f7..00000000 --- a/support/cpp/cppexp.c +++ /dev/null @@ -1,1000 +0,0 @@ -/* Parse C expressions for CCCP. - Copyright (C) 1987, 1992, 1994, 1995 Free Software Foundation. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! - -Written by Per Bothner 1994. */ - -/* Parse a C expression from text in a string */ - -#include "config.h" -#include "cpplib.h" - -#include "newalloc.h" - -//extern char *xmalloc PARAMS ((unsigned)); -//extern char *xrealloc PARAMS ((char *, unsigned)); - -#include -#ifdef MULTIBYTE_CHARS -#include -#endif - -#include -#include - -/* This is used for communicating lists of keywords with cccp.c. */ -struct arglist { - struct arglist *next; - U_CHAR *name; - int length; - int argno; -}; - -/* Define a generic NULL if one hasn't already been defined. */ - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef GENERIC_PTR -#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) -#define GENERIC_PTR void * -#else -#define GENERIC_PTR char * -#endif -#endif - -#ifndef NULL_PTR -#define NULL_PTR ((GENERIC_PTR)0) -#endif - -//extern char *xmalloc (); - -#ifndef CHAR_TYPE_SIZE -#define CHAR_TYPE_SIZE BITS_PER_UNIT -#endif - -#ifndef INT_TYPE_SIZE -#define INT_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef LONG_TYPE_SIZE -#define LONG_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE INT_TYPE_SIZE -#endif - -#ifndef MAX_CHAR_TYPE_SIZE -#define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE -#endif - -#ifndef MAX_INT_TYPE_SIZE -#define MAX_INT_TYPE_SIZE INT_TYPE_SIZE -#endif - -#ifndef MAX_LONG_TYPE_SIZE -#define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE -#endif - -#ifndef MAX_WCHAR_TYPE_SIZE -#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE -#endif - -/* Yield nonzero if adding two numbers with A's and B's signs can yield a - number with SUM's sign, where A, B, and SUM are all C integers. */ -#define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0) - -static void integer_overflow (); -static long left_shift (); -static long right_shift (); - -#define ERROR 299 -#define OROR 300 -#define ANDAND 301 -#define EQUAL 302 -#define NOTEQUAL 303 -#define LEQ 304 -#define GEQ 305 -#define LSH 306 -#define RSH 307 -#define NAME 308 -#define INT 309 -#define CHAR 310 - -#define LEFT_OPERAND_REQUIRED 1 -#define RIGHT_OPERAND_REQUIRED 2 -#define HAVE_VALUE 4 -/*#define UNSIGNEDP 8*/ - -#ifndef HOST_BITS_PER_WIDE_INT - -#if HOST_BITS_PER_LONG > HOST_BITS_PER_INT -#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG -#define HOST_WIDE_INT long -#else -#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT -#define HOST_WIDE_INT int -#endif - -#endif - -struct operation { - short op; - char rprio; /* Priority of op (relative to it right operand). */ - char flags; - char unsignedp; /* true if value should be treated as unsigned */ - HOST_WIDE_INT value; /* The value logically "right" of op. */ -}; - -/* Take care of parsing a number (anything that starts with a digit). - LEN is the number of characters in it. */ - -/* maybe needs to actually deal with floating point numbers */ - -struct operation -parse_number ( - cpp_reader *pfile, - char *start, - int olen) -{ - struct operation op; - register char *p = start; - register int c; - register unsigned long n = 0, nd, ULONG_MAX_over_base; - register int base = 10; - register int len = olen; - register int overflow = 0; - register int digit, largest_digit = 0; - int spec_long = 0; - - op.unsignedp = 0; - - for (c = 0; c < len; c++) - if (p[c] == '.') { - /* It's a float since it contains a point. */ - cpp_error (pfile, - "floating point numbers not allowed in #if expressions"); - op.op = ERROR; - return op; - } - - if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) { - p += 2; - base = 16; - len -= 2; - } - else if (*p == '0') - base = 8; - - /* Some buggy compilers (e.g. MPW C) seem to need both casts. */ - ULONG_MAX_over_base = ((unsigned long) -1) / ((unsigned long) base); - - for (; len > 0; len--) { - c = *p++; - - if (c >= '0' && c <= '9') - digit = c - '0'; - else if (base == 16 && c >= 'a' && c <= 'f') - digit = c - 'a' + 10; - else if (base == 16 && c >= 'A' && c <= 'F') - digit = c - 'A' + 10; - else { - /* `l' means long, and `u' means unsigned. */ - while (1) { - if (c == 'l' || c == 'L') - { - if (spec_long) - cpp_error (pfile, "two `l's in integer constant"); - spec_long = 1; - } - else if (c == 'u' || c == 'U') - { - if (op.unsignedp) - cpp_error (pfile, "two `u's in integer constant"); - op.unsignedp = 1; - } - else - break; - - if (--len == 0) - break; - c = *p++; - } - /* Don't look for any more digits after the suffixes. */ - break; - } - if (largest_digit < digit) - largest_digit = digit; - nd = n * base + digit; - overflow |= ((ULONG_MAX_over_base < n) | (nd < n)) ; - n = nd; - } - - if (len != 0) - { - cpp_error (pfile, "Invalid number in #if expression"); - op.op = ERROR; - return op; - } - - if (base <= largest_digit) - cpp_warning (pfile, "integer constant contains digits beyond the radix"); - - if (overflow) - cpp_warning (pfile, "integer constant out of range"); - - /* If too big to be signed, consider it unsigned. */ - if ((long) n < 0 && ! op.unsignedp) - { - if (base == 10) - cpp_warning (pfile, "integer constant is so large that it is unsigned"); - op.unsignedp = 1; - } - - op.value = n; - op.op = INT; - return op; -} - -struct token { - char *operator; - int token; -}; - -static struct token tokentab2[] = { - {"&&", ANDAND}, - {"||", OROR}, - {"<<", LSH}, - {">>", RSH}, - {"==", EQUAL}, - {"!=", NOTEQUAL}, - {"<=", LEQ}, - {">=", GEQ}, - {"++", ERROR}, - {"--", ERROR}, - {NULL, ERROR} -}; - -/* Read one token. */ - -struct operation -cpp_lex ( -cpp_reader *pfile) -{ - register int c; -/* register int namelen; */ - register struct token *toktab; - enum cpp_token token; - struct operation op; - U_CHAR *tok_start, *tok_end; - int old_written; - - retry: - - old_written = CPP_WRITTEN (pfile); - cpp_skip_hspace (pfile); - c = CPP_BUF_PEEK (CPP_BUFFER (pfile)); - if (c == '#') - return parse_number (pfile, - cpp_read_check_assertion (pfile) ? "1" : "0", 1); - - if (c == '\n') - { - op.op = 0; - return op; - } - - token = cpp_get_token (pfile); - tok_start = pfile->token_buffer + old_written; - tok_end = CPP_PWRITTEN (pfile); - pfile->limit = tok_start; - switch (token) - { - case CPP_EOF: /* Should not happen ... */ - op.op = 0; - return op; - case CPP_VSPACE: - case CPP_POP: - if (CPP_BUFFER (pfile)->fname != NULL) - { - op.op = 0; - return op; - } - goto retry; - case CPP_HSPACE: case CPP_COMMENT: - goto retry; - case CPP_NUMBER: - return parse_number (pfile, tok_start, tok_end - tok_start); - case CPP_STRING: - cpp_error (pfile, "string constants not allowed in #if expressions"); - op.op = ERROR; - return op; - case CPP_CHAR: - /* This code for reading a character constant - handles multicharacter constants and wide characters. - It is mostly copied from c-lex.c. */ - { - register int result = 0; - register int num_chars = 0; - unsigned width = MAX_CHAR_TYPE_SIZE; - int wide_flag = 0; - int max_chars; - U_CHAR *ptr = tok_start; -#ifdef MULTIBYTE_CHARS - char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + MB_CUR_MAX]; -#else - char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + 1]; -#endif - - if (*ptr == 'L') - { - ptr++; - wide_flag = 1; - width = MAX_WCHAR_TYPE_SIZE; -#ifdef MULTIBYTE_CHARS - max_chars = MB_CUR_MAX; -#else - max_chars = 1; -#endif - } - else - max_chars = MAX_LONG_TYPE_SIZE / width; - - ++ptr; - while (ptr < tok_end && ((c = *ptr++) != '\'')) - { - if (c == '\\') - { - c = cpp_parse_escape (pfile, &ptr); - if (width < HOST_BITS_PER_INT - && (unsigned) c >= (1U << width)) - cpp_pedwarn (pfile, - "escape sequence out of range for character"); - } - - num_chars++; - - /* Merge character into result; ignore excess chars. */ - if (num_chars < max_chars + 1) - { - if (width < HOST_BITS_PER_INT) - result = (result << width) | (c & ((1 << width) - 1)); - else - result = c; - token_buffer[num_chars - 1] = c; - } - } - - token_buffer[num_chars] = 0; - - if (c != '\'') - cpp_error (pfile, "malformatted character constant"); - else if (num_chars == 0) - cpp_error (pfile, "empty character constant"); - else if (num_chars > max_chars) - { - num_chars = max_chars; - cpp_error (pfile, "character constant too long"); - } - else if (num_chars != 1 && ! CPP_TRADITIONAL (pfile)) - cpp_warning (pfile, "multi-character character constant"); - - /* If char type is signed, sign-extend the constant. */ - if (! wide_flag) - { - int num_bits = num_chars * width; - - if (cpp_lookup (pfile, "__CHAR_UNSIGNED__", - sizeof ("__CHAR_UNSIGNED__")-1, -1) - || ((result >> (num_bits - 1)) & 1) == 0) - op.value - = result & ((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits)); - else - op.value - = result | ~((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits)); - } - else - { -#ifdef MULTIBYTE_CHARS - /* Set the initial shift state and convert the next sequence. */ - result = 0; - /* In all locales L'\0' is zero and mbtowc will return zero, - so don't use it. */ - if (num_chars > 1 - || (num_chars == 1 && token_buffer[0] != '\0')) - { - wchar_t wc; - (void) mbtowc (NULL_PTR, NULL_PTR, 0); - if (mbtowc (& wc, token_buffer, num_chars) == num_chars) - result = wc; - else - cpp_warning (pfile,"Ignoring invalid multibyte character"); - } -#endif - op.value = result; - } - } - - /* This is always a signed type. */ - op.unsignedp = 0; - op.op = CHAR; - - return op; - - case CPP_NAME: - return parse_number (pfile, "0", 0); - - case CPP_OTHER: - /* See if it is a special token of length 2. */ - if (tok_start + 2 == tok_end) - { - for (toktab = tokentab2; toktab->operator != NULL; toktab++) - if (tok_start[0] == toktab->operator[0] - && tok_start[1] == toktab->operator[1]) - break; - if (toktab->token == ERROR) - { - char *buf = (char *) alloca (40); - sprintf (buf, "`%s' not allowed in operand of `#if'", tok_start); - cpp_error (pfile, buf); - } - op.op = toktab->token; - return op; - } - /* fall through */ - default: - op.op = *tok_start; - return op; - } -} - - -/* Parse a C escape sequence. STRING_PTR points to a variable - containing a pointer to the string to parse. That pointer - is updated past the characters we use. The value of the - escape sequence is returned. - - A negative value means the sequence \ newline was seen, - which is supposed to be equivalent to nothing at all. - - If \ is followed by a null character, we return a negative - value and leave the string pointer pointing at the null character. - - If \ is followed by 000, we return 0 and leave the string pointer - after the zeros. A value of 0 does not mean end of string. */ - -int -cpp_parse_escape ( - cpp_reader *pfile, - char **string_ptr) -{ - register int c = *(*string_ptr)++; - switch (c) - { - case 'a': - return TARGET_BELL; - case 'b': - return TARGET_BS; - case 'e': - case 'E': - if (CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, `\\%c'", c); - return 033; - case 'f': - return TARGET_FF; - case 'n': - return TARGET_NEWLINE; - case 'r': - return TARGET_CR; - case 't': - return TARGET_TAB; - case 'v': - return TARGET_VT; - case '\n': - return -2; - case 0: - (*string_ptr)--; - return 0; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { - register int i = c - '0'; - register int count = 0; - while (++count < 3) - { - c = *(*string_ptr)++; - if (c >= '0' && c <= '7') - i = (i << 3) + c - '0'; - else - { - (*string_ptr)--; - break; - } - } - if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0) - { - i &= (1 << MAX_CHAR_TYPE_SIZE) - 1; - cpp_warning (pfile, - "octal character constant does not fit in a byte"); - } - return i; - } - case 'x': - { - register unsigned i = 0, overflow = 0, digits_found = 0, digit; - for (;;) - { - c = *(*string_ptr)++; - if (c >= '0' && c <= '9') - digit = c - '0'; - else if (c >= 'a' && c <= 'f') - digit = c - 'a' + 10; - else if (c >= 'A' && c <= 'F') - digit = c - 'A' + 10; - else - { - (*string_ptr)--; - break; - } - overflow |= i ^ (i << 4 >> 4); - i = (i << 4) + digit; - digits_found = 1; - } - if (!digits_found) - cpp_error (pfile, "\\x used with no following hex digits"); - if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1))) - { - i &= (1 << BITS_PER_UNIT) - 1; - cpp_warning (pfile, - "hex character constant does not fit in a byte"); - } - return i; - } - default: - return c; - } -} - -static void -integer_overflow ( - cpp_reader *pfile) -{ - if (CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "integer overflow in preprocessor expression"); -} - -static long -left_shift ( - cpp_reader *pfile, - long a, - int unsignedp, - unsigned long b) -{ - if (b >= HOST_BITS_PER_LONG) - { - if (! unsignedp && a != 0) - integer_overflow (pfile); - return 0; - } - else if (unsignedp) - return (unsigned long) a << b; - else - { - long l = a << b; - if (l >> b != a) - integer_overflow (pfile); - return l; - } -} - -static long -right_shift ( - cpp_reader *pfile, - long a, - int unsignedp, - unsigned long b) -{ - if (b >= HOST_BITS_PER_LONG) - return unsignedp ? 0 : a >> (HOST_BITS_PER_LONG - 1); - else if (unsignedp) - return (unsigned long) a >> b; - else - return a >> b; -} - -/* These priorities are all even, so we can handle associatively. */ -#define PAREN_INNER_PRIO 0 -#define COMMA_PRIO 4 -#define COND_PRIO (COMMA_PRIO+2) -#define OROR_PRIO (COND_PRIO+2) -#define ANDAND_PRIO (OROR_PRIO+2) -#define OR_PRIO (ANDAND_PRIO+2) -#define XOR_PRIO (OR_PRIO+2) -#define AND_PRIO (XOR_PRIO+2) -#define EQUAL_PRIO (AND_PRIO+2) -#define LESS_PRIO (EQUAL_PRIO+2) -#define SHIFT_PRIO (LESS_PRIO+2) -#define PLUS_PRIO (SHIFT_PRIO+2) -#define MUL_PRIO (PLUS_PRIO+2) -#define UNARY_PRIO (MUL_PRIO+2) -#define PAREN_OUTER_PRIO (UNARY_PRIO+2) - -#define COMPARE(OP) \ - top->unsignedp = 0;\ - top->value = (unsigned1 || unsigned2) ? (unsigned long) v1 OP (unsigned long) v2 : (v1 OP v2) - -/* Parse and evaluate a C expression, reading from PFILE. - Returns the value of the expression. */ - -HOST_WIDE_INT -cpp_parse_expr ( - cpp_reader *pfile) -{ - /* The implementation is an operator precedence parser, - i.e. a bottom-up parser, using a stack for not-yet-reduced tokens. - - The stack base is 'stack', and the current stack pointer is 'top'. - There is a stack element for each operator (only), - and the most recently pushed operator is 'top->op'. - An operand (value) is stored in the 'value' field of the stack - element of the operator that precedes it. - In that case the 'flags' field has the HAVE_VALUE flag set. */ - -#define INIT_STACK_SIZE 20 - struct operation init_stack[INIT_STACK_SIZE]; - struct operation *stack = init_stack; - struct operation *limit = stack + INIT_STACK_SIZE; - register struct operation *top = stack; - int lprio, rprio = 0; - - top->rprio = 0; - top->flags = 0; - for (;;) - { - struct operation op; - char flags = 0; - - /* Read a token */ - op = cpp_lex (pfile); - - /* See if the token is an operand, in which case go to set_value. - If the token is an operator, figure out its left and right - priorities, and then goto maybe_reduce. */ - - switch (op.op) - { - case NAME: - top->value = 0, top->unsignedp = 0; - goto set_value; - case INT: case CHAR: - top->value = op.value; - top->unsignedp = op.unsignedp; - goto set_value; - case 0: - lprio = 0; goto maybe_reduce; - case '+': case '-': - /* Is this correct if unary ? FIXME */ - flags = RIGHT_OPERAND_REQUIRED; - lprio = PLUS_PRIO; rprio = lprio + 1; goto maybe_reduce; - case '!': case '~': - flags = RIGHT_OPERAND_REQUIRED; - rprio = UNARY_PRIO; lprio = rprio + 1; goto maybe_reduce; - case '*': case '/': case '%': - lprio = MUL_PRIO; goto binop; - case '<': case '>': case LEQ: case GEQ: - lprio = LESS_PRIO; goto binop; - case EQUAL: case NOTEQUAL: - lprio = EQUAL_PRIO; goto binop; - case LSH: case RSH: - lprio = SHIFT_PRIO; goto binop; - case '&': lprio = AND_PRIO; goto binop; - case '^': lprio = XOR_PRIO; goto binop; - case '|': lprio = OR_PRIO; goto binop; - case ANDAND: lprio = ANDAND_PRIO; goto binop; - case OROR: lprio = OROR_PRIO; goto binop; - case ',': - lprio = COMMA_PRIO; goto binop; - case '(': - lprio = PAREN_OUTER_PRIO; rprio = PAREN_INNER_PRIO; - goto maybe_reduce; - case ')': - lprio = PAREN_INNER_PRIO; rprio = PAREN_OUTER_PRIO; - goto maybe_reduce; - case ':': - lprio = COND_PRIO; rprio = COND_PRIO; - goto maybe_reduce; - case '?': - lprio = COND_PRIO + 1; rprio = COND_PRIO; - goto maybe_reduce; - binop: - flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED; - rprio = lprio + 1; - goto maybe_reduce; - default: - cpp_error (pfile, "invalid character in #if"); - goto syntax_error; - } - - set_value: - /* Push a value onto the stack. */ - if (top->flags & HAVE_VALUE) - { - cpp_error (pfile, "syntax error in #if"); - goto syntax_error; - } - top->flags |= HAVE_VALUE; - continue; - - maybe_reduce: - /* Push an operator, and check if we can reduce now. */ - while (top->rprio > lprio) - { - long v1 = top[-1].value, v2 = top[0].value; - int unsigned1 = top[-1].unsignedp, unsigned2 = top[0].unsignedp; - top--; - if ((top[1].flags & LEFT_OPERAND_REQUIRED) - && ! (top[0].flags & HAVE_VALUE)) - { - cpp_error (pfile, "syntax error - missing left operand"); - goto syntax_error; - } - if ((top[1].flags & RIGHT_OPERAND_REQUIRED) - && ! (top[1].flags & HAVE_VALUE)) - { - cpp_error (pfile, "syntax error - missing right operand"); - goto syntax_error; - } - /* top[0].value = (top[1].op)(v1, v2);*/ - switch (top[1].op) - { - case '+': - if (!(top->flags & HAVE_VALUE)) - { /* Unary '+' */ - top->value = v2; - top->unsignedp = unsigned2; - top->flags |= HAVE_VALUE; - } - else - { - top->value = v1 + v2; - top->unsignedp = unsigned1 || unsigned2; - if (! top->unsignedp - && ! possible_sum_sign (v1, v2, top->value)) - integer_overflow (pfile); - } - break; - case '-': - if (!(top->flags & HAVE_VALUE)) - { /* Unary '-' */ - top->value = - v2; - if ((top->value & v2) < 0 && ! unsigned2) - integer_overflow (pfile); - top->unsignedp = unsigned2; - top->flags |= HAVE_VALUE; - } - else - { /* Binary '-' */ - top->value = v1 - v2; - top->unsignedp = unsigned1 || unsigned2; - if (! top->unsignedp - && ! possible_sum_sign (top->value, v2, v1)) - integer_overflow (pfile); - } - break; - case '*': - top->unsignedp = unsigned1 || unsigned2; - if (top->unsignedp) - top->value = (unsigned long) v1 * v2; - else - { - top->value = v1 * v2; - if (v1 - && (top->value / v1 != v2 - || (top->value & v1 & v2) < 0)) - integer_overflow (pfile); - } - break; - case '/': - if (v2 == 0) - { - cpp_error (pfile, "division by zero in #if"); - v2 = 1; - } - top->unsignedp = unsigned1 || unsigned2; - if (top->unsignedp) - top->value = (unsigned long) v1 / v2; - else - { - top->value = v1 / v2; - if ((top->value & v1 & v2) < 0) - integer_overflow (pfile); - } - break; - case '%': - if (v2 == 0) - { - cpp_error (pfile, "division by zero in #if"); - v2 = 1; - } - top->unsignedp = unsigned1 || unsigned2; - if (top->unsignedp) - top->value = (unsigned long) v1 % v2; - else - top->value = v1 % v2; - break; - case '!': - if (top->flags & HAVE_VALUE) - { - cpp_error (pfile, "syntax error"); - goto syntax_error; - } - top->value = ! v2; - top->unsignedp = 0; - top->flags |= HAVE_VALUE; - break; - case '~': - if (top->flags & HAVE_VALUE) - { - cpp_error (pfile, "syntax error"); - goto syntax_error; - } - top->value = ~ v2; - top->unsignedp = unsigned2; - top->flags |= HAVE_VALUE; - break; - case '<': COMPARE(<); break; - case '>': COMPARE(>); break; - case LEQ: COMPARE(<=); break; - case GEQ: COMPARE(>=); break; - case EQUAL: - top->value = (v1 == v2); - top->unsignedp = 0; - break; - case NOTEQUAL: - top->value = (v1 != v2); - top->unsignedp = 0; - break; - case LSH: - top->unsignedp = unsigned1; - if (v2 < 0 && ! unsigned2) - top->value = right_shift (pfile, v1, unsigned1, -v2); - else - top->value = left_shift (pfile, v1, unsigned1, v2); - break; - case RSH: - top->unsignedp = unsigned1; - if (v2 < 0 && ! unsigned2) - top->value = left_shift (pfile, v1, unsigned1, -v2); - else - top->value = right_shift (pfile, v1, unsigned1, v2); - break; -#define LOGICAL(OP) \ - top->value = v1 OP v2;\ - top->unsignedp = unsigned1 || unsigned2; - case '&': LOGICAL(&); break; - case '^': LOGICAL(^); break; - case '|': LOGICAL(|); break; - case ANDAND: - top->value = v1 && v2; top->unsignedp = 0; break; - case OROR: - top->value = v1 || v2; top->unsignedp = 0; break; - case ',': - if (CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "comma operator in operand of `#if'"); - top->value = v2; - top->unsignedp = unsigned2; - break; - case '(': case '?': - cpp_error (pfile, "syntax error in #if"); - goto syntax_error; - case ':': - if (top[0].op != '?') - { - cpp_error (pfile, - "syntax error ':' without preceding '?'"); - goto syntax_error; - } - else if (! (top[1].flags & HAVE_VALUE) - || !(top[-1].flags & HAVE_VALUE) - || !(top[0].flags & HAVE_VALUE)) - { - cpp_error (pfile, "bad syntax for ?: operator"); - goto syntax_error; - } - else - { - top--; - top->value = top->value ? v1 : v2; - top->unsignedp = unsigned1 || unsigned2; - } - break; - case ')': - if ((top[1].flags & HAVE_VALUE) - || ! (top[0].flags & HAVE_VALUE) - || top[0].op != '(' - || (top[-1].flags & HAVE_VALUE)) - { - cpp_error (pfile, "mismatched parentheses in #if"); - goto syntax_error; - } - else - { - top--; - top->value = v1; - top->unsignedp = unsigned1; - top->flags |= HAVE_VALUE; - } - break; - default: - fprintf (stderr, - top[1].op >= ' ' && top[1].op <= '~' - ? "unimplemented operator '%c'\n" - : "unimplemented operator '\\%03o'\n", - top[1].op); - } - } - if (op.op == 0) - { - if (top != stack) - cpp_error (pfile, "internal error in #if expression"); - if (stack != init_stack) - Safe_free (stack); - return top->value; - } - top++; - - /* Check for and handle stack overflow. */ - if (top == limit) - { - struct operation *new_stack; - int old_size = (char*)limit - (char*)stack; - int new_size = 2 * old_size; - if (stack != init_stack) - new_stack = (struct operation*) Safe_realloc (stack, new_size); - else - { - new_stack = (struct operation*) Safe_malloc (new_size); - bcopy ((char *) stack, (char *) new_stack, old_size); - } - stack = new_stack; - top = (struct operation*)((char*) new_stack + old_size); - limit = (struct operation*)((char*) new_stack + new_size); - } - - top->flags = flags; - top->rprio = rprio; - top->op = op.op; - } - syntax_error: - if (stack != init_stack) - Safe_free (stack); - skip_rest_of_line (pfile); - return 0; -} diff --git a/support/cpp/cpphash.c b/support/cpp/cpphash.c deleted file mode 100644 index ae3f09e1..00000000 --- a/support/cpp/cpphash.c +++ /dev/null @@ -1,220 +0,0 @@ -/* Part of CPP library. (Macro hash table support.) - Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. - Written by Per Bothner, 1994. - Based on CCCP program by by Paul Rubin, June 1986 - Adapted to ANSI C, Richard Stallman, Jan 1987 - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! */ - -#include "cpplib.h" -#include "cpphash.h" -//extern char *xmalloc PARAMS ((unsigned)); - -#include "newalloc.h" - -#include -#include - -/* Define a generic NULL if one hasn't already been defined. */ - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef __STDC__ -#define const -#define volatile -#endif - -static HASHNODE *hashtab[HASHSIZE]; - -/* - * return hash function on name. must be compatible with the one - * computed a step at a time, elsewhere - */ -int -hashf ( - register const U_CHAR *name, - register int len, - int hashsize) -{ - register int r = 0; - - while (len--) - r = HASHSTEP (r, *name++); - - return MAKE_POS (r) % hashsize; -} - -/* - * find the most recent hash node for name name (ending with first - * non-identifier char) installed by install - * - * If LEN is >= 0, it is the length of the name. - * Otherwise, compute the length by scanning the entire name. - * - * If HASH is >= 0, it is the precomputed hash code. - * Otherwise, compute the hash code. - */ -HASHNODE * -cpp_lookup ( - struct parse_file *pfile, - const U_CHAR *name, - int len, - int hash) -{ - register const U_CHAR *bp; - register HASHNODE *bucket; - - if (len < 0) - { - for (bp = name; is_idchar[*bp]; bp++) ; - len = bp - name; - } - - if (hash < 0) - hash = hashf (name, len, HASHSIZE); - - bucket = hashtab[hash]; - while (bucket) { - if (bucket->length == len && strncmp (bucket->name, name, len) == 0) - return bucket; - bucket = bucket->next; - } - return (HASHNODE*) 0; -} - -/* - * Delete a hash node. Some weirdness to free junk from macros. - * More such weirdness will have to be added if you define more hash - * types that need it. - */ - -/* Note that the DEFINITION of a macro is removed from the hash table - but its storage is not freed. This would be a storage leak - except that it is not reasonable to keep undefining and redefining - large numbers of macros many times. - In any case, this is necessary, because a macro can be #undef'd - in the middle of reading the arguments to a call to it. - If #undef freed the DEFINITION, that would crash. */ - -void -delete_macro ( - HASHNODE *hp) -{ - - if (hp->prev != NULL) - hp->prev->next = hp->next; - if (hp->next != NULL) - hp->next->prev = hp->prev; - - /* make sure that the bucket chain header that - the deleted guy was on points to the right thing afterwards. */ - if (hp == *hp->bucket_hdr) - *hp->bucket_hdr = hp->next; - - if (hp->type == T_MACRO) - { - DEFINITION *d = hp->value.defn; - struct reflist *ap, *nextap; - - for (ap = d->pattern; ap != NULL; ap = nextap) - { - nextap = ap->next; - Safe_free (ap); - } - if (d->nargs >= 0) - Safe_free (d->args.argnames); - Safe_free (d); - } - - Safe_free (hp); -} -/* - * install a name in the main hash table, even if it is already there. - * name stops with first non alphanumeric, except leading '#'. - * caller must check against redefinition if that is desired. - * delete_macro () removes things installed by install () in fifo order. - * this is important because of the `defined' special symbol used - * in #if, and also if pushdef/popdef directives are ever implemented. - * - * If LEN is >= 0, it is the length of the name. - * Otherwise, compute the length by scanning the entire name. - * - * If HASH is >= 0, it is the precomputed hash code. - * Otherwise, compute the hash code. - */ -HASHNODE * -install ( - U_CHAR *name, - int len, - enum node_type type, - int ivalue, - char *value, - int hash) -{ - register HASHNODE *hp; - register int i, bucket; - register U_CHAR *p, *q; - - if (len < 0) { - p = name; - while (is_idchar[*p]) - p++; - len = p - name; - } - - if (hash < 0) - hash = hashf (name, len, HASHSIZE); - - i = sizeof (HASHNODE) + len + 1; - hp = (HASHNODE *) Safe_malloc (i); - bucket = hash; - hp->bucket_hdr = &hashtab[bucket]; - hp->next = hashtab[bucket]; - hashtab[bucket] = hp; - hp->prev = NULL; - if (hp->next != NULL) - hp->next->prev = hp; - hp->type = type; - hp->length = len; - if (hp->type == T_CONST) - hp->value.ival = ivalue; - else - hp->value.cpval = value; - hp->name = ((U_CHAR *) hp) + sizeof (HASHNODE); - p = hp->name; - q = name; - for (i = 0; i < len; i++) - *p++ = *q++; - hp->name[len] = 0; - return hp; -} - -void -cpp_hash_cleanup ( - cpp_reader *pfile) -{ - register int i; - for (i = HASHSIZE; --i >= 0; ) - { - while (hashtab[i]) - delete_macro (hashtab[i]); - } -} diff --git a/support/cpp/cpphash.h b/support/cpp/cpphash.h deleted file mode 100644 index d0a0de31..00000000 --- a/support/cpp/cpphash.h +++ /dev/null @@ -1,37 +0,0 @@ -/* different kinds of things that can appear in the value field - of a hash node. Actually, this may be useless now. */ -union hashval { - int ival; - char *cpval; - DEFINITION *defn; -#if 0 - KEYDEF *keydef; -#endif -}; - -struct hashnode { - struct hashnode *next; /* double links for easy deletion */ - struct hashnode *prev; - struct hashnode **bucket_hdr; /* also, a back pointer to this node's hash - chain is kept, in case the node is the head - of the chain and gets deleted. */ - enum node_type type; /* type of special token */ - int length; /* length of token, for quick comparison */ - U_CHAR *name; /* the actual name */ - union hashval value; /* pointer to expansion, or whatever */ -}; - -typedef struct hashnode HASHNODE; - -/* Some definitions for the hash table. The hash function MUST be - computed as shown in hashf () below. That is because the rescan - loop computes the hash value `on the fly' for most tokens, - in order to avoid the overhead of a lot of procedure calls to - the hashf () function. Hashf () only exists for the sake of - politeness, for use when speed isn't so important. */ - -#define HASHSIZE 1403 -#define HASHSTEP(old, c) ((old << 2) + c) -#define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */ - -extern HASHNODE* install PARAMS ((U_CHAR*,int,enum node_type, int,char*,int)); diff --git a/support/cpp/cpplib.c b/support/cpp/cpplib.c deleted file mode 100644 index 5e65415f..00000000 --- a/support/cpp/cpplib.c +++ /dev/null @@ -1,7527 +0,0 @@ -/* CPP Library. - Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. - Written by Per Bothner, 1994-95. - Based on CCCP program by by Paul Rubin, June 1986 - Adapted to ANSI C, Richard Stallman, Jan 1987 - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! */ - -#if defined(_MSC_VER) - -#include "..\..\sdcc_vc.h" -#include - -#else - -#include "sdccconf.h" - -#endif - -#ifdef EMACS -#define NO_SHORTNAMES -#include "../src/config.h" -#ifdef open -#undef open -#undef read -#undef write -#endif /* open */ -#endif /* EMACS */ - - -/* The macro EMACS is defined when cpp is distributed as part of Emacs, - for the sake of machines with limited C compilers. */ -#ifndef EMACS -#include "config.h" -#include "newalloc.h" -#include -#endif /* not EMACS */ -#define GCC_INCLUDE_DIR "/usr/local/lib/gcc-lib/i386-unknown-freebsd_1.0/2.5.8/include" -#ifndef STANDARD_INCLUDE_DIR -#define STANDARD_INCLUDE_DIR "/usr/include" -#endif - -#ifndef LOCAL_INCLUDE_DIR -#define LOCAL_INCLUDE_DIR "/usr/local/include" -#endif - -#if 0 /* We can't get ptrdiff_t, so I arranged not to need PTR_INT_TYPE. */ -#ifdef __STDC__ -#define PTR_INT_TYPE ptrdiff_t -#else -#define PTR_INT_TYPE long -#endif -#endif /* 0 */ - -#include "cpplib.h" -#include "cpphash.h" - -#ifndef STDC_VALUE -#define STDC_VALUE 1 -#endif - -/* By default, colon separates directories in a path. */ -#ifndef PATH_SEPARATOR -#define PATH_SEPARATOR ':' -#endif - -#include -#include -#include -#ifdef __STDC__ -#include -#endif - - -// PENDING: Straighten this out into configure -#include // all compilers need this -#ifdef __MINGW32__ -#include -#else -#ifdef __BORLANDC__ -#include -#else -#ifndef VMS -#ifndef USG -#if !defined(_MSC_VER) -// PENDING -#include -#include /* for __DATE__ and __TIME__ */ -#include -#else -/*#include CYGNUS LOCAL: shebs -noquiet */ -// #include -#include -#include -#endif // _MSC_VER -#endif /* USG */ -#endif /* not VMS */ -#endif -#endif - -/* This defines "errno" properly for VMS, and gives us EACCES. */ -#include - -extern char *index (); -extern char *rindex (); - -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif - -#undef MIN -#undef MAX -#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) -#define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) - -/* Find the largest host integer type and set its size and type. */ - -#ifndef HOST_BITS_PER_WIDE_INT - -#if HOST_BITS_PER_LONG > HOST_BITS_PER_INT -#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG -#define HOST_WIDE_INT long -#else -#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT -#define HOST_WIDE_INT int -#endif - -#endif - -#ifndef S_ISREG -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif - -#ifndef S_ISDIR -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif - -/* Define a generic NULL if one hasn't already been defined. */ - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef GENERIC_PTR -#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) -#define GENERIC_PTR void * -#else -#define GENERIC_PTR char * -#endif -#endif - -#ifndef NULL_PTR -#define NULL_PTR ((GENERIC_PTR)0) -#endif - -#ifndef INCLUDE_LEN_FUDGE -#define INCLUDE_LEN_FUDGE 0 -#endif - -/* Symbols to predefine. */ - -#ifdef CPP_PREDEFINES -static char *predefs = CPP_PREDEFINES; -#else -static char *predefs = ""; -#endif - -/* We let tm.h override the types used here, to handle trivial differences - such as the choice of unsigned int or long unsigned int for size_t. - When machines start needing nontrivial differences in the size type, - it would be best to do something here to figure out automatically - from other information what type to use. */ - -/* The string value for __SIZE_TYPE__. */ - -#ifndef SIZE_TYPE -#define SIZE_TYPE "long unsigned int" -#endif - -/* The string value for __PTRDIFF_TYPE__. */ - -#ifndef PTRDIFF_TYPE -#define PTRDIFF_TYPE "long int" -#endif - -/* The string value for __WCHAR_TYPE__. */ - -#ifndef WCHAR_TYPE -#define WCHAR_TYPE "int" -#endif -#define CPP_WCHAR_TYPE(PFILE) \ - (CPP_OPTIONS (PFILE)->cplusplus ? "__wchar_t" : WCHAR_TYPE) - -/* The string value for __USER_LABEL_PREFIX__ */ - -#ifndef USER_LABEL_PREFIX -#define USER_LABEL_PREFIX "" -#endif - -/* The string value for __REGISTER_PREFIX__ */ - -#ifndef REGISTER_PREFIX -#define REGISTER_PREFIX "" -#endif - - -/* In the definition of a #assert name, this structure forms - a list of the individual values asserted. - Each value is itself a list of "tokens". - These are strings that are compared by name. */ - -struct tokenlist_list { - struct tokenlist_list *next; - struct arglist *tokens; -}; - -struct assertion_hashnode { - struct assertion_hashnode *next; /* double links for easy deletion */ - struct assertion_hashnode *prev; - /* also, a back pointer to this node's hash - chain is kept, in case the node is the head - of the chain and gets deleted. */ - struct assertion_hashnode **bucket_hdr; - int length; /* length of token, for quick comparison */ - U_CHAR *name; /* the actual name */ - /* List of token-sequences. */ - struct tokenlist_list *value; -}; - -#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0) -#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0) - -#define PEEKN(N) (CPP_BUFFER (pfile)->rlimit - CPP_BUFFER (pfile)->cur >= (N) ? CPP_BUFFER (pfile)->cur[N] : EOF) -#define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N)) -#define GETC() CPP_BUF_GET (CPP_BUFFER (pfile)) -#define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile)) -/* CPP_IS_MACRO_BUFFER is true if the buffer contains macro expansion. - (Note that it is false while we're expanding marco *arguments*.) */ -#define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->cleanup == macro_cleanup) - -/* Move all backslash-newline pairs out of embarrassing places. - Exchange all such pairs following BP - with any potentially-embarrassing characters that follow them. - Potentially-embarrassing characters are / and * - (because a backslash-newline inside a comment delimiter - would cause it not to be recognized). */ - -#define NEWLINE_FIX \ - do {while (PEEKC() == '\\' && PEEKN(1) == '\n') FORWARD(2); } while(0) - -/* Same, but assume we've already read the potential '\\' into C. */ -#define NEWLINE_FIX1(C) do { \ - while ((C) == '\\' && PEEKC() == '\n') { FORWARD(1); (C) = GETC(); }\ - } while(0) - -struct cpp_pending { - struct cpp_pending *next; - char *cmd; - char *arg; -}; - -/* Forward declarations. */ - -//extern char *Safe_malloc (); - -static void add_import (); -static void append_include_chain (); -static void make_assertion (); -static void path_include (); -static void initialize_builtins (); -static void initialize_char_syntax (); -extern void delete_macro (); -static int finclude (); -static void validate_else (); -static int comp_def_part (); -extern void fancy_abort (); -static int lookup_import (); -static int redundant_include_p (); -static int is_system_include (cpp_reader *, char *); -static struct file_name_map *read_name_map (); -static char *read_filename_string (); -static int open_include_file (); -static int check_macro_name (); -static int compare_defs (); -static int compare_token_lists (); -static HOST_WIDE_INT eval_if_expression (); -static int change_newlines (); -extern int hashf (); -static int file_size_and_mode (); -static struct arglist *read_token_list (); -static void free_token_list (); -static int safe_read (); -static void push_macro_expansion PARAMS ((cpp_reader *, - U_CHAR*, int, HASHNODE*)); -static struct cpp_pending *nreverse_pending PARAMS ((struct cpp_pending*)); -//extern char *xrealloc (); -//extern char *xcalloc (); -static char *savestring (); - -static void conditional_skip (); -static void skip_if_group (); - -/* Last arg to output_line_command. */ -enum file_change_code {same_file, enter_file, leave_file}; - -/* External declarations. */ - -extern HOST_WIDE_INT cpp_parse_expr PARAMS ((cpp_reader*)); - -extern char *getenv (); -extern FILE *fdopen (); -extern char *version_string; -extern struct tm *localtime (); - -/* These functions are declared to return int instead of void since they - are going to be placed in a table and some old compilers have trouble with - pointers to functions returning void. */ - -static int do_define (); -static int do_line (); -static int do_include (); -static int do_undef (); -static int do_error (); -static int do_pragma (); -static int do_ident (); -static int do_if (); -static int do_xifdef (); -static int do_else (); -static int do_elif (); -static int do_endif (); -static int do_sccs (); -static int do_once (); -static int do_assert (); -static int do_unassert (); -static int do_warning (); - -struct file_name_list - { - struct file_name_list *next; - char *fname; - /* If the following is nonzero, it is a macro name. - Don't include the file again if that macro is defined. */ - U_CHAR *control_macro; - /* If the following is nonzero, it is a C-language system include - directory. */ - int c_system_include_path; - /* Mapping of file names for this directory. */ - struct file_name_map *name_map; - /* Non-zero if name_map is valid. */ - int got_name_map; - }; - -/* If a buffer's dir field is SELF_DIR_DUMMY, it means the file was found - via the same directory as the file that #included it. */ -#define SELF_DIR_DUMMY ((struct file_name_list*)(~0)) - -/* #include "file" looks in source file dir, then stack. */ -/* #include just looks in the stack. */ -/* -I directories are added to the end, then the defaults are added. */ -/* The */ -static struct default_include { - char *fname; /* The name of the directory. */ - int cplusplus; /* Only look here if we're compiling C++. */ - int cxx_aware; /* Includes in this directory don't need to - be wrapped in extern "C" when compiling - C++. */ -} include_defaults_array[] -#ifdef INCLUDE_DEFAULTS - = INCLUDE_DEFAULTS; -#else - = { - /* Pick up GNU C++ specific include files. */ - { GPLUSPLUS_INCLUDE_DIR, 1, 1 }, -#ifdef CROSS_COMPILE - /* This is the dir for fixincludes. Put it just before - the files that we fix. */ - { GCC_INCLUDE_DIR, 0, 0 }, - /* For cross-compilation, this dir name is generated - automatically in Makefile.in. */ - { CROSS_INCLUDE_DIR, 0, 0 }, - /* This is another place that the target system's headers might be. */ - { TOOL_INCLUDE_DIR, 0, 1 }, - { LOCAL_INCLUDE_DIR, 0, 1 }, -#else /* not CROSS_COMPILE */ - /* This should be /usr/local/include and should come before - the fixincludes-fixed header files. */ - { LOCAL_INCLUDE_DIR, 0, 1 }, - /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here. - Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */ - { TOOL_INCLUDE_DIR, 0, 1 }, - /* This is the dir for fixincludes. Put it just before - the files that we fix. */ - { GCC_INCLUDE_DIR, 0, 0 }, - /* Some systems have an extra dir of include files. */ -#ifdef SYSTEM_INCLUDE_DIR - { SYSTEM_INCLUDE_DIR, 0, 0 }, -#endif - { STANDARD_INCLUDE_DIR, 0, 0 }, -#endif /* not CROSS_COMPILE */ - { 0, 0, 0 } - }; -#endif /* no INCLUDE_DEFAULTS */ - -/* `struct directive' defines one #-directive, including how to handle it. */ - -struct directive { - int length; /* Length of name */ - int (*func)(); /* Function to handle directive */ - char *name; /* Name of directive */ - enum node_type type; /* Code which describes which directive. */ - char command_reads_line; /* One if rest of line is read by func. */ - char traditional_comments; /* Nonzero: keep comments if -traditional. */ - char pass_thru; /* Copy preprocessed directive to output file.*/ -}; - -/* Here is the actual list of #-directives, most-often-used first. - The initialize_builtins function assumes #define is the very first. */ - -static struct directive directive_table[] = { - { 6, do_define, "define", T_DEFINE, 0, 1}, - { 5, do_xifdef, "ifdef", T_IFDEF, 1}, - { 6, do_xifdef, "ifndef", T_IFNDEF, 1}, - { 7, do_include, "include", T_INCLUDE, 1}, - { 12, do_include, "include_next", T_INCLUDE_NEXT, 1}, - { 6, do_include, "import", T_IMPORT, 1}, - { 5, do_endif, "endif", T_ENDIF, 1}, - { 4, do_else, "else", T_ELSE, 1}, - { 2, do_if, "if", T_IF, 1}, - { 4, do_elif, "elif", T_ELIF, 1}, - { 5, do_undef, "undef", T_UNDEF}, - { 5, do_error, "error", T_ERROR}, - { 7, do_warning, "warning", T_WARNING}, - { 6, do_pragma, "pragma", T_PRAGMA, 0, 0, 1}, - { 4, do_line, "line", T_LINE, 1}, - { 5, do_ident, "ident", T_IDENT, 1, 0, 1}, -#ifdef SCCS_DIRECTIVE - { 4, do_sccs, "sccs", T_SCCS}, -#endif - { 6, do_assert, "assert", T_ASSERT, 1}, - { 8, do_unassert, "unassert", T_UNASSERT, 1}, - { -1, 0, "", T_UNUSED}, -}; - -/* table to tell if char can be part of a C identifier. */ -U_CHAR is_idchar[256]; -/* table to tell if char can be first char of a c identifier. */ -U_CHAR is_idstart[256]; -/* table to tell if c is horizontal space. */ -U_CHAR is_hor_space[256]; -/* table to tell if c is horizontal or vertical space. */ -static U_CHAR is_space[256]; - -/* Initialize syntactic classifications of characters. */ - -static void -initialize_char_syntax ( - struct cpp_options *opts) -{ - register int i; - - /* - * Set up is_idchar and is_idstart tables. These should be - * faster than saying (is_alpha (c) || c == '_'), etc. - * Set up these things before calling any routines tthat - * refer to them. - */ - for (i = 'a'; i <= 'z'; i++) { - is_idchar[i - 'a' + 'A'] = 1; - is_idchar[i] = 1; - is_idstart[i - 'a' + 'A'] = 1; - is_idstart[i] = 1; - } - for (i = '0'; i <= '9'; i++) - is_idchar[i] = 1; - is_idchar['_'] = 1; - is_idstart['_'] = 1; - is_idchar['$'] = opts->dollars_in_ident; - is_idstart['$'] = opts->dollars_in_ident; - - /* horizontal space table */ - is_hor_space[' '] = 1; - is_hor_space['\t'] = 1; - is_hor_space['\v'] = 1; - is_hor_space['\f'] = 1; - is_hor_space['\r'] = 1; - - is_space[' '] = 1; - is_space['\t'] = 1; - is_space['\v'] = 1; - is_space['\f'] = 1; - is_space['\n'] = 1; - is_space['\r'] = 1; -} - - -/* Place into PFILE a quoted string representing the string SRC. - Caller must reserve enough space in pfile->token_buffer. */ -static void -quote_string ( - cpp_reader *pfile, - char *src) -{ - U_CHAR c; - - CPP_PUTC_Q (pfile, '\"'); - for (;;) - switch ((c = *src++)) - { - default: - if (isprint (c)) - CPP_PUTC_Q (pfile, c); - else - { - sprintf (CPP_PWRITTEN (pfile), "\\%03o", c); - CPP_ADJUST_WRITTEN (pfile, 4); - } - break; - - case '\"': - case '\\': - CPP_PUTC_Q (pfile, '\\'); - CPP_PUTC_Q (pfile, c); - break; - - case '\0': - CPP_PUTC_Q (pfile, '\"'); - CPP_NUL_TERMINATE_Q (pfile); - return; - } -} - -/* Make sure PFILE->token_buffer will hold at least N more chars. */ - -void -cpp_grow_buffer ( - cpp_reader *pfile, - long n) -{ - long old_written = CPP_WRITTEN (pfile); - pfile->token_buffer_size = n + 2 * pfile->token_buffer_size; - pfile->token_buffer = (U_CHAR*) Safe_realloc(pfile->token_buffer, pfile->token_buffer_size); - CPP_SET_WRITTEN (pfile, old_written); -} - - -/* - * process a given definition string, for initialization - * If STR is just an identifier, define it with value 1. - * If STR has anything after the identifier, then it should - * be identifier=definition. - */ - -void -cpp_define ( - cpp_reader *pfile, - U_CHAR *str) -{ - U_CHAR *buf, *p; - - buf = str; - p = str; - if (!is_idstart[*p]) - { - cpp_error (pfile, "malformed option `-D %s'", str); - return; - } - while (is_idchar[*++p]) - ; - if (*p == 0) - { - buf = (U_CHAR *) alloca (p - buf + 4); - strcpy ((char *)buf, str); - strcat ((char *)buf, " 1"); - } - else if (*p != '=') - { - cpp_error (pfile, "malformed option `-D %s'", str); - return; - } - else - { - U_CHAR *q; - /* Copy the entire option so we can modify it. */ - buf = (U_CHAR *) alloca (2 * strlen (str) + 1); - strncpy (buf, str, p - str); - /* Change the = to a space. */ - buf[p - str] = ' '; - /* Scan for any backslash-newline and remove it. */ - p++; - q = &buf[p - str]; - while (*p) - { - if (*p == '\\' && p[1] == '\n') - p += 2; - else - *q++ = *p++; - } - *q = 0; - } - - do_define (pfile, NULL, buf, buf + strlen (buf)); -} - -/* Process the string STR as if it appeared as the body of a #assert. - OPTION is the option name for which STR was the argument. */ - -static void -make_assertion ( - cpp_reader *pfile, - char *option, - U_CHAR *str) -{ - cpp_buffer *ip; -/* struct directive *kt; */ - U_CHAR *buf, *p /*, *q */ ; - - /* Copy the entire option so we can modify it. */ - buf = (U_CHAR *) alloca (strlen (str) + 1); - strcpy ((char *) buf, str); - -#if 0 - /* Scan for any backslash-newline and remove it. */ - p = q = buf; - while (*p) { - if (*p == '\\' && p[1] == '\n') - p += 2; - else - *q++ = *p++; - } - *q = 0; -#endif - - p = buf; - if (!is_idstart[*p]) { - cpp_error (pfile, "malformed option `%s %s'", option, str); - return; - } - while (is_idchar[*++p]) - ; - while (*p == ' ' || *p == '\t') p++; - if (! (*p == 0 || *p == '(')) { - cpp_error (pfile, "malformed option `%s %s'", option, str); - return; - } - - ip = cpp_push_buffer (pfile, buf, strlen (buf)); - do_assert (pfile, NULL, NULL, NULL); - cpp_pop_buffer (pfile); -} - -/* Append a chain of `struct file_name_list's - to the end of the main include chain. - FIRST is the beginning of the chain to append, and LAST is the end. */ - -static void -append_include_chain ( - cpp_reader *pfile, - struct file_name_list *first,struct file_name_list *last) -{ - struct cpp_options *opts = CPP_OPTIONS (pfile); - struct file_name_list *dir; - - if (!first || !last) - return; - - if (opts->include == 0) - opts->include = first; - else - opts->last_include->next = first; - - if (opts->first_bracket_include == 0) - opts->first_bracket_include = first; - - for (dir = first; ; dir = dir->next) { - int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE; - if (len > pfile->max_include_len) - pfile->max_include_len = len; - if (dir == last) - break; - } - - last->next = NULL; - opts->last_include = last; -} - -/* Add output to `deps_buffer' for the -M switch. - STRING points to the text to be output. - SPACER is ':' for targets, ' ' for dependencies, zero for text - to be inserted literally. */ - -static void -deps_output ( - cpp_reader *pfile, - char *string, - int spacer) -{ - int size = strlen (string); - - if (size == 0) - return; - -#ifndef MAX_OUTPUT_COLUMNS -#define MAX_OUTPUT_COLUMNS 72 -#endif - if (spacer - && pfile->deps_column > 0 - && (pfile->deps_column + size) > MAX_OUTPUT_COLUMNS) - { - deps_output (pfile, " \\\n ", 0); - pfile->deps_column = 0; - } - - if (pfile->deps_size + size + 8 > pfile->deps_allocated_size) - { - pfile->deps_allocated_size = (pfile->deps_size + size + 50) * 2; - pfile->deps_buffer = (char *) Safe_realloc(pfile->deps_buffer, - pfile->deps_allocated_size); - } - if (spacer == ' ' && pfile->deps_column > 0) - pfile->deps_buffer[pfile->deps_size++] = ' '; - bcopy (string, &pfile->deps_buffer[pfile->deps_size], size); - pfile->deps_size += size; - pfile->deps_column += size; - if (spacer == ':') - pfile->deps_buffer[pfile->deps_size++] = ':'; - pfile->deps_buffer[pfile->deps_size] = 0; -} - -/* Given a colon-separated list of file names PATH, - add all the names to the search path for include files. */ - -static void -path_include ( - cpp_reader *pfile, - char *path) -{ - char *p; - - p = path; - - if (*p) - while (1) { - char *q = p; - char *name; - struct file_name_list *dirtmp; - - /* Find the end of this name. */ - while (*q != 0 && *q != PATH_SEPARATOR) q++; - if (p == q) { - /* An empty name in the path stands for the current directory. */ - name = (char *) Safe_malloc (2); - name[0] = '.'; - name[1] = 0; - } else { - /* Otherwise use the directory that is named. */ - name = (char *) Safe_malloc (q - p + 1); - bcopy (p, name, q - p); - name[q - p] = 0; - } - - dirtmp = (struct file_name_list *) - Safe_malloc (sizeof (struct file_name_list)); - dirtmp->next = 0; /* New one goes on the end */ - dirtmp->control_macro = 0; - dirtmp->c_system_include_path = 0; - dirtmp->fname = name; - dirtmp->got_name_map = 0; - append_include_chain (pfile, dirtmp, dirtmp); - - /* Advance past this name. */ - p = q; - if (*p == 0) - break; - /* Skip the colon. */ - p++; - } -} - -void -init_parse_options ( - struct cpp_options *opts) -{ - bzero ((char *) opts, sizeof *opts); - opts->in_fname = NULL; - opts->out_fname = NULL; - - /* Initialize is_idchar to allow $. */ - opts->dollars_in_ident = 1; - initialize_char_syntax (opts); - opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 0; - - opts->no_line_commands = 0; - opts->no_trigraphs = 1; - opts->put_out_comments = 0; - opts->print_include_names = 0; - opts->dump_macros = dump_none; - opts->no_output = 0; - opts->cplusplus = 0; - opts->cplusplus_comments = 0; - - opts->verbose = 0; - opts->objc = 0; - opts->lang_asm = 0; - opts->for_lint = 0; - opts->chill = 0; - opts->pedantic_errors = 0; - opts->inhibit_warnings = 0; - opts->warn_comments = 0; - opts->warn_import = 1; - opts->warnings_are_errors = 0; -} - -enum cpp_token -null_underflow ( - cpp_reader *pfile) -{ - return CPP_EOF; -} - -int -null_cleanup ( - cpp_buffer *pbuf, - cpp_reader *pfile) -{ - return 0; -} - -int -macro_cleanup ( - cpp_buffer *pbuf, - cpp_reader *pfile) -{ - HASHNODE *macro = (HASHNODE*)pbuf->data; - if (macro->type == T_DISABLED) - macro->type = T_MACRO; - if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion) - Safe_free (pbuf->buf); - return 0; -} - -int -file_cleanup ( - cpp_buffer *pbuf, - cpp_reader *pfile) -{ - if (pbuf->buf) - { - Safe_free (pbuf->buf); - pbuf->buf = 0; - } - return 0; -} - -/* Assuming we have read '/'. - If this is the start of a comment (followed by '*' or '/'), - skip to the end of the comment, and return ' '. - Return EOF if we reached the end of file before the end of the comment. - If not the start of a comment, return '/'. */ - -static int -skip_comment ( - cpp_reader *pfile, - long *linep) -{ - int c = 0; - while (PEEKC() == '\\' && PEEKN(1) == '\n') - { - if (linep) - (*linep)++; - FORWARD(2); - } - if (PEEKC() == '*') - { - FORWARD(1); - for (;;) - { - int prev_c = c; - c = GETC (); - if (c == EOF) - return EOF; - while (c == '\\' && PEEKC() == '\n') - { - if (linep) - (*linep)++; - FORWARD(1), c = GETC(); - } - if (prev_c == '*' && c == '/') - return ' '; - if (c == '\n' && linep) - (*linep)++; - } - } - else if (PEEKC() == '/' && CPP_OPTIONS (pfile)->cplusplus_comments) - { - FORWARD(1); - for (;;) - { - c = GETC (); - if (c == EOF) - return ' '; /* Allow // to be terminated by EOF. */ - while (c == '\\' && PEEKC() == '\n') - { - FORWARD(1); - c = GETC(); - if (linep) - (*linep)++; - } - if (c == '\n') - { - /* Don't consider final '\n' to be part of comment. */ - FORWARD(-1); - return ' '; - } - } - } - else - return '/'; -} - -/* Skip whitespace \-newline and comments. Does not macro-expand. */ -void -cpp_skip_hspace ( - cpp_reader *pfile) -{ - while (1) - { - int c = PEEKC(); - if (c == EOF) - return; /* FIXME */ - if (is_hor_space[c]) - { - if ((c == '\f' || c == '\v') && CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "%s in preprocessing directive", - c == '\f' ? "formfeed" : "vertical tab"); - FORWARD(1); - } - else if (c == '/') - { - FORWARD (1); - c = skip_comment (pfile, NULL); - if (c == '/') - FORWARD(-1); - if (c == EOF || c == '/') - return; - } - else if (c == '\\' && PEEKN(1) == '\n') { - FORWARD(2); - } - else if (c == '@' && CPP_BUFFER (pfile)->has_escapes - && is_hor_space[PEEKN(1)]) - FORWARD(2); - else return; - } -} - -/* Read the rest of the current line. - The line is appended to PFILE's output buffer. */ - -void -copy_rest_of_line ( - cpp_reader *pfile) -{ - struct cpp_options *opts = CPP_OPTIONS (pfile); - for (;;) - { - int c = GETC(); - int nextc; - switch (c) - { - case EOF: - goto end_directive; - case '\\': - if (PEEKC() == '\n') - { - FORWARD (1); - continue; - } - case '\'': - case '\"': - goto scan_directive_token; - break; - case '/': - nextc = PEEKC(); - if (nextc == '*' || (opts->cplusplus_comments && nextc == '/')) - goto scan_directive_token; - break; - case '\f': - case '\v': - if (CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "%s in preprocessing directive", - c == '\f' ? "formfeed" : "vertical tab"); - break; - - case '\n': - FORWARD(-1); - goto end_directive; - scan_directive_token: - FORWARD(-1); - cpp_get_token (pfile); - continue; - } - CPP_PUTC (pfile, c); - } - end_directive: ; - CPP_NUL_TERMINATE (pfile); -} - -void -skip_rest_of_line ( - cpp_reader *pfile) -{ - long old = CPP_WRITTEN (pfile); - copy_rest_of_line (pfile); - CPP_SET_WRITTEN (pfile, old); -} - -/* Handle a possible # directive. - '#' has already been read. */ - -int -handle_directive ( - cpp_reader *pfile) -{ int c; - register struct directive *kt; - int ident_length; - long after_ident = 0; - U_CHAR *ident, *line_end; - long old_written = CPP_WRITTEN (pfile); - - cpp_skip_hspace (pfile); - - c = PEEKC (); - if (c >= '0' && c <= '9') - { - /* Handle # followed by a line number. */ - if (CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "`#' followed by integer"); - do_line (pfile, NULL); - goto done_a_directive; - } - - /* Now find the directive name. */ - CPP_PUTC (pfile, '#'); - parse_name (pfile, GETC()); - ident = pfile->token_buffer + old_written + 1; - ident_length = CPP_PWRITTEN (pfile) - ident; - if (ident_length == 0 && PEEKC() == '\n') - { - /* A line of just `#' becomes blank. */ - goto done_a_directive; - } - -#if 0 - if (ident_length == 0 || !is_idstart[*ident]) { - U_CHAR *p = ident; - while (is_idchar[*p]) { - if (*p < '0' || *p > '9') - break; - p++; - } - /* Avoid error for `###' and similar cases unless -pedantic. */ - if (p == ident) { - while (*p == '#' || is_hor_space[*p]) p++; - if (*p == '\n') { - if (pedantic && !lang_asm) - cpp_warning (pfile, "invalid preprocessor directive"); - return 0; - } - } - - if (!lang_asm) - cpp_error (pfile, "invalid preprocessor directive name"); - - return 0; - } -#endif - /* - * Decode the keyword and call the appropriate expansion - * routine, after moving the input pointer up to the next line. - */ - for (kt = directive_table; ; kt++) { - if (kt->length <= 0) - goto not_a_directive; - if (kt->length == ident_length && !strncmp (kt->name, ident, ident_length)) - break; - } - - if (! kt->command_reads_line) - { - /* Nonzero means do not delete comments within the directive. - #define needs this when -traditional. */ - int comments = CPP_TRADITIONAL (pfile) && kt->traditional_comments; - int save_put_out_comments = CPP_OPTIONS (pfile)->put_out_comments; - CPP_OPTIONS (pfile)->put_out_comments = comments; - after_ident = CPP_WRITTEN (pfile); - copy_rest_of_line (pfile); - CPP_OPTIONS (pfile)->put_out_comments = save_put_out_comments; - } - - /* For #pragma and #define, we may want to pass through the directive. - Other directives may create output, but we don't want the directive - itself out, so we pop it now. For example #include may write a - command (see comment in do_include), and conditionals may emit - #failed ... #endfailed stuff. But note that popping the buffer - means the parameters to kt->func may point after pfile->limit - so these parameters are invalid as soon as something gets appended - to the token_buffer. */ - - line_end = CPP_PWRITTEN (pfile); - if (!kt->pass_thru && kt->type != T_DEFINE) - CPP_SET_WRITTEN (pfile, old_written); - - (*kt->func) (pfile, kt, pfile->token_buffer + after_ident, line_end); - if (kt->pass_thru - || (kt->type == T_DEFINE - && CPP_OPTIONS (pfile)->dump_macros == dump_definitions)) - { - /* Just leave the entire #define in the output stack. */ - } - else if (kt->type == T_DEFINE - && CPP_OPTIONS (pfile)->dump_macros == dump_names) - { - U_CHAR *p = pfile->token_buffer + old_written + 7; /* Skip "#define". */ - SKIP_WHITE_SPACE (p); - while (is_idchar[*p]) p++; - pfile->limit = p; - CPP_PUTC (pfile, '\n'); - } - else if (kt->type == T_DEFINE) - CPP_SET_WRITTEN (pfile, old_written); - done_a_directive: - return 1; - - not_a_directive: - return 0; -} - -/* Pass a directive through to the output file. - BUF points to the contents of the directive, as a contiguous string. - LIMIT points to the first character past the end of the directive. - KEYWORD is the keyword-table entry for the directive. */ - -static void -pass_thru_directive ( - U_CHAR *buf, U_CHAR *limit, - cpp_reader *pfile, - struct directive *keyword) -{ - register unsigned keyword_length = keyword->length; - - CPP_RESERVE (pfile, 1 + keyword_length + (limit - buf)); - CPP_PUTC_Q (pfile, '#'); - CPP_PUTS_Q (pfile, keyword->name, keyword_length); - if (limit != buf && buf[0] != ' ') - CPP_PUTC_Q (pfile, ' '); - CPP_PUTS_Q (pfile, buf, limit - buf); -#if 0 - CPP_PUTS_Q (pfile, '\n'); - /* Count the line we have just made in the output, - to get in sync properly. */ - pfile->lineno++; -#endif -} - -/* The arglist structure is built by do_define to tell - collect_definition where the argument names begin. That - is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist - would contain pointers to the strings x, y, and z. - Collect_definition would then build a DEFINITION node, - with reflist nodes pointing to the places x, y, and z had - appeared. So the arglist is just convenience data passed - between these two routines. It is not kept around after - the current #define has been processed and entered into the - hash table. */ - -struct arglist { - struct arglist *next; - U_CHAR *name; - int length; - int argno; - char rest_args; -}; - -/* Read a replacement list for a macro with parameters. - Build the DEFINITION structure. - Reads characters of text starting at BUF until END. - ARGLIST specifies the formal parameters to look for - in the text of the definition; NARGS is the number of args - in that list, or -1 for a macro name that wants no argument list. - MACRONAME is the macro name itself (so we can avoid recursive expansion) - and NAMELEN is its length in characters. - - Note that comments, backslash-newlines, and leading white space - have already been deleted from the argument. */ - -static DEFINITION * -collect_expansion ( - cpp_reader *pfile, - U_CHAR *buf, U_CHAR *limit, - int nargs, - struct arglist *arglist) -{ - DEFINITION *defn; - register U_CHAR *p, *lastp, *exp_p; - struct reflist *endpat = NULL; - /* Pointer to first nonspace after last ## seen. */ - U_CHAR *concat = 0; - /* Pointer to first nonspace after last single-# seen. */ - U_CHAR *stringify = 0; - int maxsize; - int expected_delimiter = '\0'; - - /* Scan thru the replacement list, ignoring comments and quoted - strings, picking up on the macro calls. It does a linear search - thru the arg list on every potential symbol. Profiling might say - that something smarter should happen. */ - - if (limit < buf) - abort (); - - /* Find the beginning of the trailing whitespace. */ - p = buf; - while (p < limit && is_space[limit[-1]]) limit--; - - /* Allocate space for the text in the macro definition. - Leading and trailing whitespace chars need 2 bytes each. - Each other input char may or may not need 1 byte, - so this is an upper bound. The extra 5 are for invented - leading and trailing newline-marker and final null. */ - maxsize = (sizeof (DEFINITION) - + (limit - p) + 5); - /* Occurrences of '@' get doubled, so allocate extra space for them. */ - while (p < limit) - if (*p++ == '@') - maxsize++; - defn = (DEFINITION *) Safe_calloc(1,maxsize); - - defn->nargs = nargs; - exp_p = defn->expansion = (U_CHAR *) defn + sizeof (DEFINITION); - lastp = exp_p; - - p = buf; - - /* Add one initial space escape-marker to prevent accidental - token-pasting (often removed by macroexpand). */ - *exp_p++ = '@'; - *exp_p++ = ' '; - - if (limit - p >= 2 && p[0] == '#' && p[1] == '#') { - cpp_error (pfile, "`##' at start of macro definition"); - p += 2; - } - - /* Process the main body of the definition. */ - while (p < limit) { - int skipped_arg = 0; - register U_CHAR c = *p++; - - *exp_p++ = c; - - if (!CPP_TRADITIONAL (pfile)) { - switch (c) { - case '\'': - case '\"': - if (expected_delimiter != '\0') { - if (c == expected_delimiter) - expected_delimiter = '\0'; - } else - expected_delimiter = c; - break; - - case '\\': - if (p < limit && expected_delimiter) { - /* In a string, backslash goes through - and makes next char ordinary. */ - *exp_p++ = *p++; - } - break; - - case '@': - /* An '@' in a string or character constant stands for itself, - and does not need to be escaped. */ - if (!expected_delimiter) - *exp_p++ = c; - break; - - case '#': - /* # is ordinary inside a string. */ - if (expected_delimiter) - break; - if (p < limit && *p == '#') { - /* ##: concatenate preceding and following tokens. */ - /* Take out the first #, discard preceding whitespace. */ - exp_p--; - while (exp_p > lastp && is_hor_space[exp_p[-1]]) - --exp_p; - /* Skip the second #. */ - p++; - /* Discard following whitespace. */ - SKIP_WHITE_SPACE (p); - concat = p; - if (p == limit) - cpp_error (pfile, "`##' at end of macro definition"); - } else if (nargs >= 0) { - /* Single #: stringify following argument ref. - Don't leave the # in the expansion. */ - exp_p--; - SKIP_WHITE_SPACE (p); - if (p == limit || ! is_idstart[*p]) - cpp_error (pfile, - "`#' operator is not followed by a macro argument name"); - else - stringify = p; - } - break; - } - } else { - /* In -traditional mode, recognize arguments inside strings and - and character constants, and ignore special properties of #. - Arguments inside strings are considered "stringified", but no - extra quote marks are supplied. */ - switch (c) { - case '\'': - case '\"': - if (expected_delimiter != '\0') { - if (c == expected_delimiter) - expected_delimiter = '\0'; - } else - expected_delimiter = c; - break; - - case '\\': - /* Backslash quotes delimiters and itself, but not macro args. */ - if (expected_delimiter != 0 && p < limit - && (*p == expected_delimiter || *p == '\\')) { - *exp_p++ = *p++; - continue; - } - break; - - case '/': - if (expected_delimiter != '\0') /* No comments inside strings. */ - break; - if (*p == '*') { - /* If we find a comment that wasn't removed by handle_directive, - this must be -traditional. So replace the comment with - nothing at all. */ - exp_p--; - p += 1; - while (p < limit && !(p[-2] == '*' && p[-1] == '/')) - p++; -#if 0 - /* Mark this as a concatenation-point, as if it had been ##. */ - concat = p; -#endif - } - else if (*p == '/') { - /* A c++ comment. Discard to the end of line */ - exp_p--; - p = limit; - } - break; - } - } - - /* Handle the start of a symbol. */ - if (is_idchar[c] && nargs > 0) { - U_CHAR *id_beg = p - 1; - int id_len; - - --exp_p; - while (p != limit && is_idchar[*p]) p++; - id_len = p - id_beg; - - if (is_idstart[c]) { - register struct arglist *arg; - - for (arg = arglist; arg != NULL; arg = arg->next) { - struct reflist *tpat; - - if (arg->name[0] == c - && arg->length == id_len - && strncmp (arg->name, id_beg, id_len) == 0) { - if (expected_delimiter && CPP_OPTIONS (pfile)->warn_stringify) { - if (CPP_TRADITIONAL (pfile)) { - cpp_warning (pfile, "macro argument `%.*s' is stringified.", - id_len, arg->name); - } else { - cpp_warning (pfile, - "macro arg `%.*s' would be stringified with -traditional.", - id_len, arg->name); - } - } - /* If ANSI, don't actually substitute inside a string. */ - if (!CPP_TRADITIONAL (pfile) && expected_delimiter) - break; - /* make a pat node for this arg and append it to the end of - the pat list */ - tpat = (struct reflist *) Safe_malloc (sizeof (struct reflist)); - tpat->next = NULL; - tpat->raw_before = concat == id_beg; - tpat->raw_after = 0; - tpat->rest_args = arg->rest_args; - tpat->stringify = (CPP_TRADITIONAL (pfile) - ? expected_delimiter != '\0' - : stringify == id_beg); - - if (endpat == NULL) - defn->pattern = tpat; - else - endpat->next = tpat; - endpat = tpat; - - tpat->argno = arg->argno; - tpat->nchars = exp_p - lastp; - { - register U_CHAR *p1 = p; - SKIP_WHITE_SPACE (p1); - if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#') - tpat->raw_after = 1; - } - lastp = exp_p; /* place to start copying from next time */ - skipped_arg = 1; - break; - } - } - } - - /* If this was not a macro arg, copy it into the expansion. */ - if (! skipped_arg) { - register U_CHAR *lim1 = p; - p = id_beg; - while (p != lim1) - *exp_p++ = *p++; - if (stringify == id_beg) - cpp_error (pfile, - "`#' operator should be followed by a macro argument name"); - } - } - } - - if (!CPP_TRADITIONAL (pfile) && expected_delimiter == 0) - { - /* If ANSI, put in a "@ " marker to prevent token pasting. - But not if "inside a string" (which in ANSI mode - happens only for -D option). */ - *exp_p++ = '@'; - *exp_p++ = ' '; - } - - *exp_p = '\0'; - - defn->length = exp_p - defn->expansion; - - /* Crash now if we overrun the allocated size. */ - if (defn->length + 1 > maxsize) - abort (); - -#if 0 -/* This isn't worth the time it takes. */ - /* give back excess storage */ - defn->expansion = (U_CHAR *) Safe_realloc(defn->expansion, defn->length + 1); -#endif - - return defn; -} - -/* - * special extension string that can be added to the last macro argument to - * allow it to absorb the "rest" of the arguments when expanded. Ex: - * #define wow(a, b...) process (b, a, b) - * { wow (1, 2, 3); } -> { process (2, 3, 1, 2, 3); } - * { wow (one, two); } -> { process (two, one, two); } - * if this "rest_arg" is used with the concat token '##' and if it is not - * supplied then the token attached to with ## will not be outputted. Ex: - * #define wow (a, b...) process (b ## , a, ## b) - * { wow (1, 2); } -> { process (2, 1, 2); } - * { wow (one); } -> { process (one); { - */ -static char rest_extension[] = "..."; -#define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1) - -/* Create a DEFINITION node from a #define directive. Arguments are - as for do_define. */ -static MACRODEF -create_definition ( - U_CHAR *buf, U_CHAR *limit, - cpp_reader *pfile, - int predefinition) -{ - U_CHAR *bp; /* temp ptr into input buffer */ - U_CHAR *symname; /* remember where symbol name starts */ - int sym_length; /* and how long it is */ - int rest_args = 0; - long line, col; - char *file = CPP_BUFFER (pfile) ? CPP_BUFFER (pfile)->nominal_fname : ""; - DEFINITION *defn; - int arglengths = 0; /* Accumulate lengths of arg names - plus number of args. */ - MACRODEF mdef; - cpp_buf_line_and_col (CPP_BUFFER (pfile), &line, &col); - - bp = buf; - - while (is_hor_space[*bp]) - bp++; - - symname = bp; /* remember where it starts */ - - sym_length = check_macro_name (pfile, bp, "macro"); - bp += sym_length; - - /* Lossage will occur if identifiers or control keywords are broken - across lines using backslash. This is not the right place to take - care of that. */ - - if (*bp == '(') { - struct arglist *arg_ptrs = NULL; - int argno = 0; - - bp++; /* skip '(' */ - SKIP_WHITE_SPACE (bp); - - /* Loop over macro argument names. */ - while (*bp != ')') { - struct arglist *temp; - - temp = (struct arglist *) alloca (sizeof (struct arglist)); - temp->name = bp; - temp->next = arg_ptrs; - temp->argno = argno++; - temp->rest_args = 0; - arg_ptrs = temp; - - if (rest_args) - cpp_pedwarn (pfile, "another parameter follows `%s'", rest_extension); - - if (!is_idstart[*bp]) - cpp_pedwarn (pfile, "invalid character in macro parameter name"); - - /* Find the end of the arg name. */ - while (is_idchar[*bp]) { - bp++; - /* do we have a "special" rest-args extension here? */ - if (limit - bp > REST_EXTENSION_LENGTH && - strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) { - rest_args = 1; - temp->rest_args = 1; - break; - } - } - temp->length = bp - temp->name; - if (rest_args == 1) - bp += REST_EXTENSION_LENGTH; - arglengths += temp->length + 2; - SKIP_WHITE_SPACE (bp); - if (temp->length == 0 || (*bp != ',' && *bp != ')')) { - cpp_error (pfile, "badly punctuated parameter list in `#define'"); - goto nope; - } - if (*bp == ',') { - bp++; - SKIP_WHITE_SPACE (bp); - } - if (bp >= limit) { - cpp_error (pfile, "unterminated parameter list in `#define'"); - goto nope; - } - { - struct arglist *otemp; - - for (otemp = temp->next; otemp != NULL; otemp = otemp->next) - if (temp->length == otemp->length && - strncmp (temp->name, otemp->name, temp->length) == 0) { - U_CHAR *name; - - name = (U_CHAR *) alloca (temp->length + 1); - (void) strncpy (name, temp->name, temp->length); - name[temp->length] = '\0'; - cpp_error (pfile, - "duplicate argument name `%s' in `#define'", name); - goto nope; - } - } - } - - ++bp; /* skip paren */ - SKIP_WHITE_SPACE (bp); - /* now everything from bp before limit is the definition. */ - defn = collect_expansion (pfile, bp, limit, argno, arg_ptrs); - defn->rest_args = rest_args; - - /* Now set defn->args.argnames to the result of concatenating - the argument names in reverse order - with comma-space between them. */ - defn->args.argnames = (U_CHAR *) Safe_malloc (arglengths + 1); - { - struct arglist *temp; - int i = 0; - for (temp = arg_ptrs; temp; temp = temp->next) { - bcopy (temp->name, &defn->args.argnames[i], temp->length); - i += temp->length; - if (temp->next != 0) { - defn->args.argnames[i++] = ','; - defn->args.argnames[i++] = ' '; - } - } - defn->args.argnames[i] = 0; - } - } else { - /* Simple expansion or empty definition. */ - - if (bp < limit) - { - if (is_hor_space[*bp]) { - bp++; - SKIP_WHITE_SPACE (bp); - } else { - switch (*bp) { - case '!': case '"': case '#': case '%': case '&': case '\'': - case ')': case '*': case '+': case ',': case '-': case '.': - case '/': case ':': case ';': case '<': case '=': case '>': - case '?': case '[': case '\\': case ']': case '^': case '{': - case '|': case '}': case '~': - cpp_warning (pfile, "missing white space after `#define %.*s'", - sym_length, symname); - break; - - default: - cpp_pedwarn (pfile, "missing white space after `#define %.*s'", - sym_length, symname); - break; - } - } - } - /* now everything from bp before limit is the definition. */ - defn = collect_expansion (pfile, bp, limit, -1,(struct arglist *) NULL_PTR); - defn->args.argnames = (U_CHAR *) ""; - } - - defn->line = line; - defn->file = file; - - /* OP is null if this is a predefinition */ - defn->predefined = predefinition; - mdef.defn = defn; - mdef.symnam = symname; - mdef.symlen = sym_length; - - return mdef; - - nope: - mdef.defn = 0; - return mdef; -} - -/* Check a purported macro name SYMNAME, and yield its length. - USAGE is the kind of name this is intended for. */ - -static int -check_macro_name ( - cpp_reader *pfile, - U_CHAR *symname, - char *usage) -{ - U_CHAR *p; - int sym_length; - - for (p = symname; is_idchar[*p]; p++) - ; - sym_length = p - symname; - if (sym_length == 0) - cpp_error (pfile, "invalid %s name", usage); - else if (!is_idstart[*symname]) { - U_CHAR *msg; /* what pain... */ - msg = (U_CHAR *) alloca (sym_length + 1); - bcopy (symname, msg, sym_length); - msg[sym_length] = 0; - cpp_error (pfile, "invalid %s name `%s'", usage, msg); - } else { - if (! strncmp (symname, "defined", 7) && sym_length == 7) - cpp_error (pfile, "invalid %s name `defined'", usage); - } - return sym_length; -} - -/* - * return zero if two DEFINITIONs are isomorphic - */ -static int -compare_defs ( - DEFINITION *d1, DEFINITION *d2) -{ - register struct reflist *a1, *a2; - register U_CHAR *p1 = d1->expansion; - register U_CHAR *p2 = d2->expansion; - int first = 1; - - if (d1->nargs != d2->nargs) - return 1; - if (strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames)) - return 1; - for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2; - a1 = a1->next, a2 = a2->next) { - if (!((a1->nchars == a2->nchars && ! strncmp (p1, p2, a1->nchars)) - || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0)) - || a1->argno != a2->argno - || a1->stringify != a2->stringify - || a1->raw_before != a2->raw_before - || a1->raw_after != a2->raw_after) - return 1; - first = 0; - p1 += a1->nchars; - p2 += a2->nchars; - } - if (a1 != a2) - return 1; - if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion), - p2, d2->length - (p2 - d2->expansion), 1)) - return 1; - return 0; -} - -/* Return 1 if two parts of two macro definitions are effectively different. - One of the parts starts at BEG1 and has LEN1 chars; - the other has LEN2 chars at BEG2. - Any sequence of whitespace matches any other sequence of whitespace. - FIRST means these parts are the first of a macro definition; - so ignore leading whitespace entirely. - LAST means these parts are the last of a macro definition; - so ignore trailing whitespace entirely. */ - -static int -comp_def_part ( - int first, - U_CHAR *beg1, int len1, - U_CHAR *beg2, int len2 , - int last) -{ - register U_CHAR *end1 = beg1 + len1; - register U_CHAR *end2 = beg2 + len2; - if (first) { - while (beg1 != end1 && is_space[*beg1]) beg1++; - while (beg2 != end2 && is_space[*beg2]) beg2++; - } - if (last) { - while (beg1 != end1 && is_space[end1[-1]]) end1--; - while (beg2 != end2 && is_space[end2[-1]]) end2--; - } - while (beg1 != end1 && beg2 != end2) { - if (is_space[*beg1] && is_space[*beg2]) { - while (beg1 != end1 && is_space[*beg1]) beg1++; - while (beg2 != end2 && is_space[*beg2]) beg2++; - } else if (*beg1 == *beg2) { - beg1++; beg2++; - } else break; - } - return (beg1 != end1) || (beg2 != end2); -} - -/* Process a #define command. -BUF points to the contents of the #define command, as a contiguous string. -LIMIT points to the first character past the end of the definition. -KEYWORD is the keyword-table entry for #define, -or NULL for a "predefined" macro. */ - -static int -do_define ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *buf, U_CHAR *limit) -{ - int hashcode; - MACRODEF mdef; - HASHNODE *hp; - -#if 0 - /* If this is a precompiler run (with -pcp) pass thru #define commands. */ - if (pcp_outfile && keyword) - pass_thru_directive (buf, limit, pfile, keyword); -#endif - - mdef = create_definition (buf, limit, pfile, keyword == NULL); - if (mdef.defn == 0) - goto nope; - - hashcode = hashf (mdef.symnam, mdef.symlen, HASHSIZE); - - if ((hp = cpp_lookup (pfile, mdef.symnam, mdef.symlen, hashcode)) != NULL) - { - int ok = 0; - /* Redefining a precompiled key is ok. */ - if (hp->type == T_PCSTRING) - ok = 1; - /* Redefining a macro is ok if the definitions are the same. */ - else if (hp->type == T_MACRO) - ok = ! compare_defs (mdef.defn, hp->value.defn); - /* Redefining a constant is ok with -D. */ - else if (hp->type == T_CONST) - ok = ! CPP_OPTIONS (pfile)->done_initializing; - /* Print the warning if it's not ok. */ - if (!ok) - { - U_CHAR *msg; /* what pain... */ - - /* If we are passing through #define and #undef directives, do - that for this re-definition now. */ - if (CPP_OPTIONS (pfile)->debug_output && keyword) - pass_thru_directive (buf, limit, pfile, keyword); - - msg = (U_CHAR *) alloca (mdef.symlen + 22); - *msg = '`'; - bcopy (mdef.symnam, msg + 1, mdef.symlen); - strcpy ((char *) (msg + mdef.symlen + 1), "' redefined"); - cpp_pedwarn (pfile, msg); - if (hp->type == T_MACRO) - cpp_pedwarn_with_file_and_line (pfile, hp->value.defn->file, hp->value.defn->line, - "this is the location of the previous definition"); - } - /* Replace the old definition. */ - hp->type = T_MACRO; - hp->value.defn = mdef.defn; - } - else - { - /* If we are passing through #define and #undef directives, do - that for this new definition now. */ - if (CPP_OPTIONS (pfile)->debug_output && keyword) - pass_thru_directive (buf, limit, pfile, keyword); - install (mdef.symnam, mdef.symlen, T_MACRO, 0, - (char *) mdef.defn, hashcode); - } - - return 0; - -nope: - - return 1; -} - -/* This structure represents one parsed argument in a macro call. - `raw' points to the argument text as written (`raw_length' is its length). - `expanded' points to the argument's macro-expansion - (its length is `expand_length'). - `stringified_length' is the length the argument would have - if stringified. - `use_count' is the number of times this macro arg is substituted - into the macro. If the actual use count exceeds 10, - the value stored is 10. */ - -/* raw and expanded are relative to ARG_BASE */ -#define ARG_BASE ((pfile)->token_buffer) - -struct argdata { - /* Strings relative to pfile->token_buffer */ - long raw, expanded, stringified; - int raw_length, expand_length; - int stringified_length; - char newlines; - char use_count; -}; - - -cpp_buffer* -cpp_push_buffer ( - cpp_reader *pfile, - U_CHAR *buffer, - long length) -{ -#ifdef STATIC_BUFFERS - register cpp_buffer *buf = CPP_BUFFER (pfile); - if (buf == pfile->buffer_stack) - fatal ("%s: macro or `#include' recursion too deep", buf->fname); - buf--; - bzero ((char *) buf, sizeof (cpp_buffer)); - CPP_BUFFER (pfile) = buf; -#else - register cpp_buffer *buf = (cpp_buffer*) Safe_malloc (sizeof(cpp_buffer)); - bzero ((char *) buf, sizeof (cpp_buffer)); - CPP_PREV_BUFFER (buf) = CPP_BUFFER (pfile); - CPP_BUFFER (pfile) = buf; -#endif - buf->if_stack = pfile->if_stack; - buf->cleanup = null_cleanup; - buf->underflow = null_underflow; - buf->buf = buf->cur = buffer; - buf->alimit = buf->rlimit = buffer + length; - - return buf; -} - -cpp_buffer* -cpp_pop_buffer (pfile) - cpp_reader *pfile; -{ - cpp_buffer *buf = CPP_BUFFER (pfile); -#ifdef STATIC_BUFFERS - (*buf->cleanup) (buf, pfile); - return ++CPP_BUFFER (pfile); -#else - cpp_buffer *next_buf = CPP_PREV_BUFFER (buf); - (*buf->cleanup) (buf, pfile); - CPP_BUFFER (pfile) = next_buf; - Safe_free (buf); - return next_buf; -#endif -} - -/* Scan until CPP_BUFFER (PFILE) is exhausted into PFILE->token_buffer. - Pop the buffer when done. */ - -void -cpp_scan_buffer ( - cpp_reader *pfile ) -{ - cpp_buffer *buffer = CPP_BUFFER (pfile); - for (;;) - { - enum cpp_token token = cpp_get_token (pfile); - if (token == CPP_EOF) /* Should not happen ... */ - break; - if (token == CPP_POP && CPP_BUFFER (pfile) == buffer) - { - cpp_pop_buffer (pfile); - break; - } - } -} - -/* - * Rescan a string (which may have escape marks) into pfile's buffer. - * Place the result in pfile->token_buffer. - * - * The input is copied before it is scanned, so it is safe to pass - * it something from the token_buffer that will get overwritten - * (because it follows CPP_WRITTEN). This is used by do_include. - */ - -static void -cpp_expand_to_buffer ( - cpp_reader *pfile, - U_CHAR *buf, - int length) -{ - register cpp_buffer *ip; - U_CHAR *limit = buf + length; - U_CHAR *buf1; -#if 0 - cpp_buffer obuf; - int odepth = indepth; -#endif - - if (length < 0) - abort (); - - /* Set up the input on the input stack. */ - - buf1 = (U_CHAR *) alloca (length + 1); - { - register U_CHAR *p1 = buf; - register U_CHAR *p2 = buf1; - - while (p1 != limit) - *p2++ = *p1++; - } - buf1[length] = 0; - - ip = cpp_push_buffer (pfile, buf1, length); - ip->has_escapes = 1; -#if 0 - ip->lineno = obuf.lineno = 1; -#endif - - /* Scan the input, create the output. */ - cpp_scan_buffer (pfile); - -#if 0 - if (indepth != odepth) - abort (); -#endif - - CPP_NUL_TERMINATE (pfile); -} - - -static void -adjust_position ( - U_CHAR *buf, - U_CHAR *limit, - long *linep, - long *colp) -{ - while (buf < limit) - { - U_CHAR ch = *buf++; - if (ch == '\n') - (*linep)++, (*colp) = 1; - else - (*colp)++; - } -} - -/* Move line_base forward, updating lineno and colno. */ - -static void -update_position ( - register cpp_buffer *pbuf) -{ - unsigned char *old_pos = pbuf->buf + pbuf->line_base; - unsigned char *new_pos = pbuf->cur; - register struct parse_marker *mark; - for (mark = pbuf->marks; mark != NULL; mark = mark->next) - { - if (pbuf->buf + mark->position < new_pos) - new_pos = pbuf->buf + mark->position; - } - pbuf->line_base += new_pos - old_pos; - adjust_position (old_pos, new_pos, &pbuf->lineno, &pbuf->colno); -} - -void -cpp_buf_line_and_col ( - register cpp_buffer *pbuf, - long *linep,long *colp) -{ - long dummy; - if (colp == NULL) - colp = &dummy; - if (pbuf) - { - *linep = pbuf->lineno; - *colp = pbuf->colno; - adjust_position (pbuf->buf + pbuf->line_base, pbuf->cur, linep, colp); - } - else - { - *linep = 0; - *colp = 0; - } -} - -/* Return the cpp_buffer that corresponds to a file (not a macro). */ - -cpp_buffer* -cpp_file_buffer ( - cpp_reader *pfile) -{ - cpp_buffer *ip = CPP_BUFFER (pfile); - - for ( ; ip != CPP_NULL_BUFFER (pfile); ip = CPP_PREV_BUFFER (ip)) - if (ip->fname != NULL) - return ip; - return NULL; -} - -static long -count_newlines ( - register U_CHAR *buf, - register U_CHAR *limit) -{ - register long count = 0; - while (buf < limit) - { - U_CHAR ch = *buf++; - if (ch == '\n') - count++; - } - return count; -} - -/* - * write out a #line command, for instance, after an #include file. - * If CONDITIONAL is nonzero, we can omit the #line if it would - * appear to be a no-op, and we can output a few newlines instead - * if we want to increase the line number by a small amount. - * FILE_CHANGE says whether we are entering a file, leaving, or neither. - */ - -static void -output_line_command ( - cpp_reader *pfile, - int conditional, - enum file_change_code file_change) -{ -/* int len;*/ -/* char *line_cmd_buf, *line_end;*/ - long line, col; - cpp_buffer *ip = CPP_BUFFER (pfile); - - if (ip->fname == NULL || CPP_OPTIONS (pfile)->no_output) { - return; - } - - update_position (ip); - line = CPP_BUFFER (pfile)->lineno; - col = CPP_BUFFER (pfile)->colno; - adjust_position (CPP_LINE_BASE (ip), ip->cur, &line, &col); - - if (CPP_OPTIONS (pfile)->no_line_commands) - return; - - if (conditional) { - if (line == pfile->lineno) - return; - - /* If the inherited line number is a little too small, - output some newlines instead of a #line command. */ - if (line > pfile->lineno && line < pfile->lineno + 8) { - CPP_RESERVE (pfile, 20); - while (line > pfile->lineno) { - CPP_PUTC_Q (pfile, '\n'); - pfile->lineno++; - } - return; - } - } - -#if 0 - /* Don't output a line number of 0 if we can help it. */ - if (ip->lineno == 0 && ip->bufp - ip->buf < ip->length - && *ip->bufp == '\n') { - ip->lineno++; - ip->bufp++; - } -#endif - - CPP_RESERVE (pfile, 4 * strlen (ip->nominal_fname) + 50); - { - static char sharp_line[] = "#line "; - - CPP_PUTS_Q (pfile, sharp_line, sizeof(sharp_line)-1); - } - - sprintf (CPP_PWRITTEN (pfile), "%ld ", line+2); - CPP_ADJUST_WRITTEN (pfile, strlen (CPP_PWRITTEN (pfile))); - -// modification for SDC51 - if (*ip->nominal_fname == '\0') - quote_string (pfile,"standard input"); - else - quote_string (pfile, ip->nominal_fname); - if (file_change != same_file) { - CPP_PUTC_Q (pfile, ' '); - CPP_PUTC_Q (pfile, file_change == enter_file ? '1' : '2'); - } - /* Tell cc1 if following text comes from a system header file. */ - if (ip->system_header_p) { - CPP_PUTC_Q (pfile, ' '); - CPP_PUTC_Q (pfile, '3'); - } -#ifndef NO_IMPLICIT_EXTERN_C - /* Tell cc1plus if following text should be treated as C. */ - if (ip->system_header_p == 2 && CPP_OPTIONS (pfile)->cplusplus) { - CPP_PUTC_Q (pfile, ' '); - CPP_PUTC_Q (pfile, '4'); - } -#endif - CPP_PUTC_Q (pfile, '\n'); - pfile->lineno = line; -} - -/* - * Parse a macro argument and append the info on PFILE's token_buffer. - * REST_ARGS means to absorb the rest of the args. - * Return nonzero to indicate a syntax error. - */ - -static enum cpp_token -macarg ( - cpp_reader *pfile, - int rest_args) -{ - int paren = 0; - enum cpp_token token = CPP_EOF; - /* long arg_start = CPP_WRITTEN (pfile); */ - char save_put_out_comments = CPP_OPTIONS (pfile)->put_out_comments; - CPP_OPTIONS (pfile)->put_out_comments = 0; - - /* Try to parse as much of the argument as exists at this - input stack level. */ - pfile->no_macro_expand++; - for (;;) - { - token = cpp_get_token (pfile); - switch (token) - { - case CPP_EOF: - goto done; - case CPP_POP: - /* If we've hit end of file, it's an error (reported by caller). - Ditto if it's the end of cpp_expand_to_buffer text. - If we've hit end of macro, just continue. */ - if (! CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) - goto done; - break; - case CPP_LPAREN: - paren++; - break; - case CPP_RPAREN: - if (--paren < 0) - goto found; - break; - case CPP_COMMA: - /* if we've returned to lowest level and - we aren't absorbing all args */ - if (paren == 0 && rest_args == 0) - goto found; - break; - found: - /* Remove ',' or ')' from argument buffer. */ - CPP_ADJUST_WRITTEN (pfile, -1); - goto done; - default: ; - } - } - - done: - CPP_OPTIONS (pfile)->put_out_comments = save_put_out_comments; - pfile->no_macro_expand--; - - return token; -} - -/* Turn newlines to spaces in the string of length LENGTH at START, - except inside of string constants. - The string is copied into itself with its beginning staying fixed. */ - -static int -change_newlines ( - U_CHAR *start, - int length) -{ - register U_CHAR *ibp; - register U_CHAR *obp; - register U_CHAR *limit; - register int c; - - ibp = start; - limit = start + length; - obp = start; - - while (ibp < limit) { - *obp++ = c = *ibp++; - switch (c) { - - case '\'': - case '\"': - /* Notice and skip strings, so that we don't delete newlines in them. */ - { - int quotec = c; - while (ibp < limit) { - *obp++ = c = *ibp++; - if (c == quotec) - break; - if (c == '\n' && quotec == '\'') - break; - } - } - break; - } - } - - return obp - start; -} - - -static struct tm * -timestamp ( - cpp_reader *pfile) -{ - if (!pfile->timebuf) { - time_t t = time ((time_t *)0); - pfile->timebuf = localtime (&t); - } - return pfile->timebuf; -} - -static char *monthnames[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", - }; - -/* - * expand things like __FILE__. Place the expansion into the output - * buffer *without* rescanning. - */ - -static void -special_symbol ( - HASHNODE *hp, - cpp_reader *pfile) -{ - char *buf; - int /* i, */ len; - int true_indepth; - cpp_buffer *ip = NULL; - struct tm *timebuf; - - int paren = 0; /* For special `defined' keyword */ - -#if 0 - if (pcp_outfile && pcp_inside_if - && hp->type != T_SPEC_DEFINED && hp->type != T_CONST) - cpp_error (pfile, - "Predefined macro `%s' used inside `#if' during precompilation", - hp->name); -#endif - - for (ip = CPP_BUFFER (pfile); ; ip = CPP_PREV_BUFFER (ip)) - { - if (ip == NULL) - { - cpp_error (pfile, "cccp error: not in any file?!"); - return; /* the show must go on */ - } - if (ip->fname != NULL) - break; - } - - switch (hp->type) - { - case T_FILE: - case T_BASE_FILE: - { - char *string; - if (hp->type == T_BASE_FILE) - { - while (CPP_PREV_BUFFER (ip)) - ip = CPP_PREV_BUFFER (ip); - } - string = ip->nominal_fname; - - if (!string) - string = ""; - CPP_RESERVE (pfile, 3 + 4 * strlen (string)); - quote_string (pfile, string); - return; - } - - case T_INCLUDE_LEVEL: - true_indepth = 0; - for (ip = CPP_BUFFER (pfile); ip != NULL; ip = CPP_PREV_BUFFER (ip)) - if (ip->fname != NULL) - true_indepth++; - - buf = (char *) alloca (8); /* Eight bytes ought to be more than enough */ - sprintf (buf, "%d", true_indepth - 1); - break; - - case T_VERSION: - buf = (char *) alloca (3 + strlen (version_string)); - sprintf (buf, "\"%s\"", version_string); - break; - -#ifndef NO_BUILTIN_SIZE_TYPE - case T_SIZE_TYPE: - buf = SIZE_TYPE; - break; -#endif - -#ifndef NO_BUILTIN_PTRDIFF_TYPE - case T_PTRDIFF_TYPE: - buf = PTRDIFF_TYPE; - break; -#endif - - case T_WCHAR_TYPE: - buf = CPP_WCHAR_TYPE (pfile); - break; - - case T_USER_LABEL_PREFIX_TYPE: - buf = USER_LABEL_PREFIX; - break; - - case T_REGISTER_PREFIX_TYPE: - buf = REGISTER_PREFIX; - break; - - case T_CONST: - buf = (char *) alloca (4 * sizeof (int)); - sprintf (buf, "%d", hp->value.ival); -#if 0 - if (pcp_inside_if && pcp_outfile) - /* Output a precondition for this macro use */ - fprintf (pcp_outfile, "#define %s %d\n", hp->name, hp->value.ival); -#endif - break; - - case T_SPECLINE: - { - long line = ip->lineno; - long col = ip->colno; - adjust_position (CPP_LINE_BASE (ip), ip->cur, &line, &col); - - buf = (char *) alloca (10); - sprintf (buf, "%ld", line); - } - break; - - case T_DATE: - case T_TIME: - buf = (char *) alloca (20); - timebuf = timestamp (pfile); - if (hp->type == T_DATE) - sprintf (buf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon], - timebuf->tm_mday, timebuf->tm_year + 1900); - else - sprintf (buf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min, - timebuf->tm_sec); - break; - - case T_SPEC_DEFINED: - buf = " 0 "; /* Assume symbol is not defined */ - ip = CPP_BUFFER (pfile); - SKIP_WHITE_SPACE (ip->cur); - if (*ip->cur == '(') - { - paren++; - ip->cur++; /* Skip over the paren */ - SKIP_WHITE_SPACE (ip->cur); - } - - if (!is_idstart[*ip->cur]) - goto oops; - if ((hp = cpp_lookup (pfile, ip->cur, -1, -1)) != 0) - { -#if 0 - if (pcp_outfile && pcp_inside_if - && (hp->type == T_CONST - || (hp->type == T_MACRO && hp->value.defn->predefined))) - /* Output a precondition for this macro use. */ - fprintf (pcp_outfile, "#define %s\n", hp->name); -#endif - buf = " 1 "; - } -#if 0 - else - if (pcp_outfile && pcp_inside_if) - { - /* Output a precondition for this macro use */ - U_CHAR *cp = ip->bufp; - fprintf (pcp_outfile, "#undef "); - while (is_idchar[*cp]) /* Ick! */ - fputc (*cp++, pcp_outfile); - putc ('\n', pcp_outfile); - } -#endif - while (is_idchar[*ip->cur]) - ++ip->cur; - SKIP_WHITE_SPACE (ip->cur); - if (paren) - { - if (*ip->cur != ')') - goto oops; - ++ip->cur; - } - break; - - oops: - - cpp_error (pfile, "`defined' without an identifier"); - break; - - default: - cpp_error (pfile, "cccp error: invalid special hash type"); /* time for gdb */ - abort (); - } - len = strlen (buf); - CPP_RESERVE (pfile, len + 1); - CPP_PUTS_Q (pfile, buf, len); - CPP_NUL_TERMINATE_Q (pfile); - - return; -} - -/* Initialize the built-in macros. */ - -static void -initialize_builtins ( - cpp_reader *pfile) -{ - install ("__LINE__", -1, T_SPECLINE, 0, 0, -1); - install ("__DATE__", -1, T_DATE, 0, 0, -1); - install ("__FILE__", -1, T_FILE, 0, 0, -1); - install ("__BASE_FILE__", -1, T_BASE_FILE, 0, 0, -1); - install ("__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, 0, 0, -1); - install ("__VERSION__", -1, T_VERSION, 0, 0, -1); -#ifndef NO_BUILTIN_SIZE_TYPE - install ("__SIZE_TYPE__", -1, T_SIZE_TYPE, 0, 0, -1); -#endif -#ifndef NO_BUILTIN_PTRDIFF_TYPE - install ("__PTRDIFF_TYPE__ ", -1, T_PTRDIFF_TYPE, 0, 0, -1); -#endif - install ("__WCHAR_TYPE__", -1, T_WCHAR_TYPE, 0, 0, -1); - install ("__USER_LABEL_PREFIX__", -1, T_USER_LABEL_PREFIX_TYPE, 0, 0, -1); - install ("__REGISTER_PREFIX__", -1, T_REGISTER_PREFIX_TYPE, 0, 0, -1); - install ("__TIME__", -1, T_TIME, 0, 0, -1); - if (!CPP_TRADITIONAL (pfile)) - install ("__STDC__", -1, T_CONST, STDC_VALUE, 0, -1); - if (CPP_OPTIONS (pfile)->objc) - install ("__OBJC__", -1, T_CONST, 1, 0, -1); -/* This is supplied using a -D by the compiler driver - so that it is present only when truly compiling with GNU C. */ -/* install ("__GNUC__", -1, T_CONST, 2, 0, -1); */ - - if (CPP_OPTIONS (pfile)->debug_output) - { - char directive[2048]; - register struct directive *dp = &directive_table[0]; - struct tm *timebuf = timestamp (pfile); - cpp_buffer *pbuffer = CPP_BUFFER (pfile); - - while (CPP_PREV_BUFFER (pbuffer)) - pbuffer = CPP_PREV_BUFFER (pbuffer); - sprintf (directive, " __BASE_FILE__ \"%s\"\n", - pbuffer->nominal_fname); - output_line_command (pfile, 0, same_file); - pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp); - - sprintf (directive, " __VERSION__ \"%s\"\n", version_string); - output_line_command (pfile, 0, same_file); - pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp); - -#ifndef NO_BUILTIN_SIZE_TYPE - sprintf (directive, " __SIZE_TYPE__ %s\n", SIZE_TYPE); - output_line_command (pfile, 0, same_file); - pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp); -#endif - -#ifndef NO_BUILTIN_PTRDIFF_TYPE - sprintf (directive, " __PTRDIFF_TYPE__ %s\n", PTRDIFF_TYPE); - output_line_command (pfile, 0, same_file); - pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp); -#endif - - sprintf (directive, " __WCHAR_TYPE__ %s\n", CPP_WCHAR_TYPE (pfile)); - output_line_command (pfile, 0, same_file); - pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp); - - sprintf (directive, " __DATE__ \"%s %2d %4d\"\n", - monthnames[timebuf->tm_mon], - timebuf->tm_mday, timebuf->tm_year + 1900); - output_line_command (pfile, 0, same_file); - pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp); - - sprintf (directive, " __TIME__ \"%02d:%02d:%02d\"\n", - timebuf->tm_hour, timebuf->tm_min, timebuf->tm_sec); - output_line_command (pfile, 0, same_file); - pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp); - - if (!CPP_TRADITIONAL (pfile)) - { - sprintf (directive, " __STDC__ 1"); - output_line_command (pfile, 0, same_file); - pass_thru_directive (directive, &directive[strlen (directive)], - pfile, dp); - } - if (CPP_OPTIONS (pfile)->objc) - { - sprintf (directive, " __OBJC__ 1"); - output_line_command (pfile, 0, same_file); - pass_thru_directive (directive, &directive[strlen (directive)], - pfile, dp); - } - } -} - -/* Return 1 iff a token ending in C1 followed directly by a token C2 - could cause mis-tokenization. */ - -static int -unsafe_chars ( - int c1, int c2) -{ - switch (c1) - { - case '+': case '-': - if (c2 == c1 || c2 == '=') - return 1; - goto letter; - case '.': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case 'e': case 'E': - if (c2 == '-' || c2 == '+') - return 1; /* could extend a pre-processing number */ - goto letter; - case 'L': - if (c2 == '\'' || c2 == '\"') - return 1; /* Could turn into L"xxx" or L'xxx'. */ - goto letter; - letter: - case '_': - case 'a': case 'b': case 'c': case 'd': case 'f': - case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': - case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': - case 's': case 't': case 'u': case 'v': case 'w': case 'x': - case 'y': case 'z': - case 'A': case 'B': case 'C': case 'D': case 'F': - case 'G': case 'H': case 'I': case 'J': case 'K': - case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': - case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': - case 'Y': case 'Z': - /* We're in the middle of either a name or a pre-processing number. */ - return (is_idchar[c2] || c2 == '.'); - case '<': case '>': case '!': case '%': case '#': case ':': - case '^': case '&': case '|': case '*': case '/': case '=': - return (c2 == c1 || c2 == '='); - } - return 0; -} - -/* Expand a macro call. - HP points to the symbol that is the macro being called. - Put the result of expansion onto the input stack - so that subsequent input by our caller will use it. - - If macro wants arguments, caller has already verified that - an argument list follows; arguments come from the input stack. */ - -static void -macroexpand ( - cpp_reader *pfile, - HASHNODE *hp) -{ - int nargs; - DEFINITION *defn = hp->value.defn; - register U_CHAR *xbuf; - long start_line, start_column; - int xbuf_len; - struct argdata *args; - long old_written = CPP_WRITTEN (pfile); -#if 0 - int start_line = instack[indepth].lineno; -#endif - int rest_args, rest_zero; - register int i; - -#if 0 - CHECK_DEPTH (return;); -#endif - -#if 0 - /* This macro is being used inside a #if, which means it must be */ - /* recorded as a precondition. */ - if (pcp_inside_if && pcp_outfile && defn->predefined) - dump_single_macro (hp, pcp_outfile); -#endif - - pfile->output_escapes++; - cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column); - - nargs = defn->nargs; - - if (nargs >= 0) - { - enum cpp_token token = CPP_EOF; - - args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata)); - - for (i = 0; i < nargs; i++) - { - args[i].raw = args[i].expanded = 0; - args[i].raw_length = 0; - args[i].expand_length = args[i].stringified_length = -1; - args[i].use_count = 0; - } - - /* Parse all the macro args that are supplied. I counts them. - The first NARGS args are stored in ARGS. - The rest are discarded. If rest_args is set then we assume - macarg absorbed the rest of the args. */ - i = 0; - rest_args = 0; - rest_args = 0; - FORWARD(1); /* Discard the open-parenthesis before the first arg. */ - do - { - if (rest_args) - continue; - if (i < nargs || (nargs == 0 && i == 0)) - { - /* if we are working on last arg which absorbs rest of args... */ - if (i == nargs - 1 && defn->rest_args) - rest_args = 1; - args[i].raw = CPP_WRITTEN (pfile); - token = macarg (pfile, rest_args); - args[i].raw_length = CPP_WRITTEN (pfile) - args[i].raw; - args[i].newlines = 0; /* FIXME */ - } - else - token = macarg (pfile, 0); - if (token == CPP_EOF || token == CPP_POP) - { - cpp_error_with_line (pfile, start_line, start_column, - "unterminated macro call"); - return; - } - i++; - } while (token == CPP_COMMA); - - /* If we got one arg but it was just whitespace, call that 0 args. */ - if (i == 1) - { - register U_CHAR *bp = ARG_BASE + args[0].raw; - register U_CHAR *lim = bp + args[0].raw_length; - /* cpp.texi says for foo ( ) we provide one argument. - However, if foo wants just 0 arguments, treat this as 0. */ - if (nargs == 0) - while (bp != lim && is_space[*bp]) bp++; - if (bp == lim) - i = 0; - } - - /* Don't output an error message if we have already output one for - a parse error above. */ - rest_zero = 0; - if (nargs == 0 && i > 0) - { - cpp_error (pfile, "arguments given to macro `%s'", hp->name); - } - else if (i < nargs) - { - /* traditional C allows foo() if foo wants one argument. */ - if (nargs == 1 && i == 0 && CPP_TRADITIONAL (pfile)) - ; - /* the rest args token is allowed to absorb 0 tokens */ - else if (i == nargs - 1 && defn->rest_args) - rest_zero = 1; - else if (i == 0) - cpp_error (pfile, "macro `%s' used without args", hp->name); - else if (i == 1) - cpp_error (pfile, "macro `%s' used with just one arg", hp->name); - else - cpp_error (pfile, "macro `%s' used with only %d args", - hp->name, i); - } - else if (i > nargs) - { - cpp_error (pfile, - "macro `%s' used with too many (%d) args", hp->name, i); - } - } - - /* If macro wants zero args, we parsed the arglist for checking only. - Read directly from the macro definition. */ - if (nargs <= 0) - { - xbuf = defn->expansion; - xbuf_len = defn->length; - } - else - { - register U_CHAR *exp = defn->expansion; - register int offset; /* offset in expansion, - copied a piece at a time */ - register int totlen; /* total amount of exp buffer filled so far */ - - register struct reflist *ap, *last_ap; - - /* Macro really takes args. Compute the expansion of this call. */ - - /* Compute length in characters of the macro's expansion. - Also count number of times each arg is used. */ - xbuf_len = defn->length; - for (ap = defn->pattern; ap != NULL; ap = ap->next) - { - if (ap->stringify) - { - register struct argdata *arg = &args[ap->argno]; - /* Stringify it it hasn't already been */ - if (arg->stringified_length < 0) - { - int arglen = arg->raw_length; - int escaped = 0; - int in_string = 0; - int c; - /* Initially need_space is -1. Otherwise, 1 means the - previous character was a space, but we suppressed it; - 0 means the previous character was a non-space. */ - int need_space = -1; - i = 0; - arg->stringified = CPP_WRITTEN (pfile); - if (!CPP_TRADITIONAL (pfile)) - CPP_PUTC (pfile, '\"'); /* insert beginning quote */ - for (; i < arglen; i++) - { - c = (ARG_BASE + arg->raw)[i]; - - if (! in_string) - { - /* Internal sequences of whitespace are replaced by - one space except within an string or char token.*/ - if (is_space[c]) - { - if (CPP_WRITTEN (pfile) > arg->stringified - && (CPP_PWRITTEN (pfile))[-1] == '@') - { - /* "@ " escape markers are removed */ - CPP_ADJUST_WRITTEN (pfile, -1); - continue; - } - if (need_space == 0) - need_space = 1; - continue; - } - else if (need_space > 0) - CPP_PUTC (pfile, ' '); - need_space = 0; - } - - if (escaped) - escaped = 0; - else - { - if (c == '\\') - escaped = 1; - if (in_string) - { - if (c == in_string) - in_string = 0; - } - else if (c == '\"' || c == '\'') - in_string = c; - } - - /* Escape these chars */ - if (c == '\"' || (in_string && c == '\\')) - CPP_PUTC (pfile, '\\'); - if (isprint (c)) - CPP_PUTC (pfile, c); - else - { - CPP_RESERVE (pfile, 4); - sprintf (CPP_PWRITTEN (pfile), "\\%03o", - (unsigned int) c); - CPP_ADJUST_WRITTEN (pfile, 4); - } - } - if (!CPP_TRADITIONAL (pfile)) - CPP_PUTC (pfile, '\"'); /* insert ending quote */ - arg->stringified_length - = CPP_WRITTEN (pfile) - arg->stringified; - } - xbuf_len += args[ap->argno].stringified_length; - } - else if (ap->raw_before || ap->raw_after || CPP_TRADITIONAL (pfile)) - /* Add 4 for two newline-space markers to prevent - token concatenation. */ - xbuf_len += args[ap->argno].raw_length + 4; - else - { - /* We have an ordinary (expanded) occurrence of the arg. - So compute its expansion, if we have not already. */ - if (args[ap->argno].expand_length < 0) - { - args[ap->argno].expanded = CPP_WRITTEN (pfile); - cpp_expand_to_buffer (pfile, - ARG_BASE + args[ap->argno].raw, - args[ap->argno].raw_length); - - args[ap->argno].expand_length - = CPP_WRITTEN (pfile) - args[ap->argno].expanded; - } - - /* Add 4 for two newline-space markers to prevent - token concatenation. */ - xbuf_len += args[ap->argno].expand_length + 4; - } - if (args[ap->argno].use_count < 10) - args[ap->argno].use_count++; - } - - xbuf = (U_CHAR *) Safe_malloc (xbuf_len + 1); - - /* Generate in XBUF the complete expansion - with arguments substituted in. - TOTLEN is the total size generated so far. - OFFSET is the index in the definition - of where we are copying from. */ - offset = totlen = 0; - for (last_ap = NULL, ap = defn->pattern; ap != NULL; - last_ap = ap, ap = ap->next) - { - register struct argdata *arg = &args[ap->argno]; - int count_before = totlen; - - /* Add chars to XBUF. */ - for (i = 0; i < ap->nchars; i++, offset++) - xbuf[totlen++] = exp[offset]; - - /* If followed by an empty rest arg with concatenation, - delete the last run of nonwhite chars. */ - if (rest_zero && totlen > count_before - && ((ap->rest_args && ap->raw_before) - || (last_ap != NULL && last_ap->rest_args - && last_ap->raw_after))) - { - /* Delete final whitespace. */ - while (totlen > count_before && is_space[xbuf[totlen - 1]]) - totlen--; - - /* Delete the nonwhites before them. */ - while (totlen > count_before && ! is_space[xbuf[totlen - 1]]) - totlen--; - } - - if (ap->stringify != 0) - { - bcopy (ARG_BASE + arg->stringified, - xbuf + totlen, arg->stringified_length); - totlen += arg->stringified_length; - } - else if (ap->raw_before || ap->raw_after || CPP_TRADITIONAL (pfile)) - { - U_CHAR *p1 = ARG_BASE + arg->raw; - U_CHAR *l1 = p1 + arg->raw_length; - if (ap->raw_before) - { - while (p1 != l1 && is_space[*p1]) p1++; - while (p1 != l1 && is_idchar[*p1]) - xbuf[totlen++] = *p1++; - } - if (ap->raw_after) - { - /* Arg is concatenated after: delete trailing whitespace, - whitespace markers, and no-reexpansion markers. */ - while (p1 != l1) - { - if (is_space[l1[-1]]) l1--; - else if (l1[-1] == '-') - { - U_CHAR *p2 = l1 - 1; - /* If a `-' is preceded by an odd number of newlines then it - and the last newline are a no-reexpansion marker. */ - while (p2 != p1 && p2[-1] == '\n') p2--; - if ((l1 - 1 - p2) & 1) { - l1 -= 2; - } - else break; - } - else break; - } - } - - bcopy (p1, xbuf + totlen, l1 - p1); - totlen += l1 - p1; - } - else - { - U_CHAR *expanded = ARG_BASE + arg->expanded; - if (!ap->raw_before && totlen > 0 && arg->expand_length - && !CPP_TRADITIONAL(pfile) - && unsafe_chars (xbuf[totlen-1], expanded[0])) - { - xbuf[totlen++] = '@'; - xbuf[totlen++] = ' '; - } - - bcopy (expanded, xbuf + totlen, arg->expand_length); - totlen += arg->expand_length; - - if (!ap->raw_after && totlen > 0 && offset < defn->length - && !CPP_TRADITIONAL(pfile) - && unsafe_chars (xbuf[totlen-1], exp[offset])) - { - xbuf[totlen++] = '@'; - xbuf[totlen++] = ' '; - } - - /* If a macro argument with newlines is used multiple times, - then only expand the newlines once. This avoids creating - output lines which don't correspond to any input line, - which confuses gdb and gcov. */ - if (arg->use_count > 1 && arg->newlines > 0) - { - /* Don't bother doing change_newlines for subsequent - uses of arg. */ - arg->use_count = 1; - arg->expand_length - = change_newlines (expanded, arg->expand_length); - } - } - - if (totlen > xbuf_len) - abort (); - } - - /* if there is anything left of the definition - after handling the arg list, copy that in too. */ - - for (i = offset; i < defn->length; i++) - { - /* if we've reached the end of the macro */ - if (exp[i] == ')') - rest_zero = 0; - if (! (rest_zero && last_ap != NULL && last_ap->rest_args - && last_ap->raw_after)) - xbuf[totlen++] = exp[i]; - } - - xbuf[totlen] = 0; - xbuf_len = totlen; - - } - - pfile->output_escapes--; - - /* Now put the expansion on the input stack - so our caller will commence reading from it. */ - push_macro_expansion (pfile, xbuf, xbuf_len, hp); - CPP_BUFFER (pfile)->has_escapes = 1; - - /* Pop the space we've used in the token_buffer for argument expansion. */ - CPP_SET_WRITTEN (pfile, old_written); - - /* Recursive macro use sometimes works traditionally. - #define foo(x,y) bar (x (y,0), y) - foo (foo, baz) */ - - if (!CPP_TRADITIONAL (pfile)) - hp->type = T_DISABLED; -} - -static void -push_macro_expansion ( - cpp_reader *pfile, - register U_CHAR *xbuf, - int xbuf_len, - HASHNODE *hp) -{ - register cpp_buffer *mbuf = cpp_push_buffer (pfile, xbuf, xbuf_len); - mbuf->cleanup = macro_cleanup; - mbuf->data = hp; - - /* The first chars of the expansion should be a "@ " added by - collect_expansion. This is to prevent accidental token-pasting - between the text preceding the macro invocation, and the macro - expansion text. - - We would like to avoid adding unneeded spaces (for the sake of - tools that use cpp, such as imake). In some common cases we can - tell that it is safe to omit the space. - - The character before the macro invocation cannot have been an - idchar (or else it would have been pasted with the idchars of - the macro name). Therefore, if the first non-space character - of the expansion is an idchar, we do not need the extra space - to prevent token pasting. - - Also, we don't need the extra space if the first char is '(', - or some other (less common) characters. */ - - if (xbuf[0] == '@' && xbuf[1] == ' ' - && (is_idchar[xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\'' - || xbuf[2] == '\"')) - mbuf->cur += 2; -} - -/* Like cpp_get_token, except that it does not read past end-of-line. - Also, horizontal space is skipped, and macros are popped. */ - -static enum cpp_token -get_directive_token ( - cpp_reader *pfile) -{ - for (;;) - { - long old_written = CPP_WRITTEN (pfile); - enum cpp_token token; - cpp_skip_hspace (pfile); - if (PEEKC () == '\n') - return CPP_VSPACE; - token = cpp_get_token (pfile); - switch (token) - { - case CPP_POP: - if (! CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) - return token; - /* ... else fall though ... */ - case CPP_HSPACE: case CPP_COMMENT: - CPP_SET_WRITTEN (pfile, old_written); - break; - default: - return token; - } - } -} - -/* Handle #include and #import. - This function expects to see "fname" or on the input. - - The input is normally in part of the output_buffer following - CPP_WRITTEN, and will get overwritten by output_line_command. - I.e. in input file specification has been popped by handle_directive. - This is safe. */ - -static int -do_include ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *unused1, U_CHAR *unused2) -{ - int importing = (keyword->type == T_IMPORT); - int skip_dirs = (keyword->type == T_INCLUDE_NEXT); - char *fname; /* Dynamically allocated fname buffer */ - char *pcftry; -/* char *pcfname;*/ - U_CHAR *fbeg, *fend; /* Beginning and end of fname */ - enum cpp_token token; - - /* Chain of dirs to search */ - struct file_name_list *search_start = CPP_OPTIONS (pfile)->include; - struct file_name_list dsp[1]; /* First in chain, if #include "..." */ - struct file_name_list *searchptr = 0; - long old_written = CPP_WRITTEN (pfile); - - int flen; - - int f; /* file number */ - - int angle_brackets = 0; /* 0 for "...", 1 for <...> */ - /* int pcf = -1; */ - char *pcfbuf; -/* char *pcfbuflimit;*/ - int pcfnum; - f= -1; /* JF we iz paranoid! */ - - if (importing && CPP_OPTIONS (pfile)->warn_import - && !CPP_OPTIONS (pfile)->inhibit_warnings - && !CPP_BUFFER (pfile)->system_header_p && !pfile->import_warning) - { - pfile->import_warning = 1; - cpp_warning (pfile, "using `#import' is not recommended"); - fprintf (stderr, "The fact that a certain header file need not be processed more than once\n"); - fprintf (stderr, "should be indicated in the header file, not where it is used.\n"); - fprintf (stderr, "The best way to do this is with a conditional of this form:\n\n"); - fprintf (stderr, " #ifndef _FOO_H_INCLUDED\n"); - fprintf (stderr, " #define _FOO_H_INCLUDED\n"); - fprintf (stderr, " ... ...\n"); - fprintf (stderr, " #endif /* Not _FOO_H_INCLUDED */\n\n"); - fprintf (stderr, "Then users can use `#include' any number of times.\n"); - fprintf (stderr, "GNU C automatically avoids processing the file more than once\n"); - fprintf (stderr, "when it is equipped with such a conditional.\n"); - } - - pfile->parsing_include_directive++; - token = get_directive_token (pfile); - pfile->parsing_include_directive--; - - if (token == CPP_STRING) - { - /* FIXME - check no trailing garbage */ - fbeg = pfile->token_buffer + old_written + 1; - fend = CPP_PWRITTEN (pfile) - 1; - if (fbeg[-1] == '<') - { - angle_brackets = 1; - /* If -I-, start with the first -I dir after the -I-. */ - if (CPP_OPTIONS (pfile)->first_bracket_include) - search_start = CPP_OPTIONS (pfile)->first_bracket_include; - } - /* If -I- was specified, don't search current dir, only spec'd ones. */ - else if (! CPP_OPTIONS (pfile)->ignore_srcdir) - { - cpp_buffer *fp; - /* We have "filename". Figure out directory this source - file is coming from and put it on the front of the list. */ - - for (fp = CPP_BUFFER (pfile); fp != NULL; fp = CPP_PREV_BUFFER (fp)) - { - int n; - char *ep,*nam; - - if ((nam = fp->nominal_fname) != NULL) - { - /* Found a named file. Figure out dir of the file, - and put it in front of the search list. */ - dsp[0].next = search_start; - search_start = dsp; -#ifndef VMS - ep = rindex (nam, '/'); -#else /* VMS */ - ep = rindex (nam, ']'); - if (ep == NULL) ep = rindex (nam, '>'); - if (ep == NULL) ep = rindex (nam, ':'); - if (ep != NULL) ep++; -#endif /* VMS */ - if (ep != NULL) - { - n = ep - nam; - dsp[0].fname = (char *) alloca (n + 1); - strncpy (dsp[0].fname, nam, n); - dsp[0].fname[n] = '\0'; - if (n + INCLUDE_LEN_FUDGE > pfile->max_include_len) - pfile->max_include_len = n + INCLUDE_LEN_FUDGE; - } - else - { - dsp[0].fname = 0; /* Current directory */ - } - dsp[0].got_name_map = 0; - break; - } - } - } - } -#ifdef VMS - else if (token == CPP_NAME) - { - /* - * Support '#include xyz' like VAX-C to allow for easy use of all the - * decwindow include files. It defaults to '#include ' (so the - * code from case '<' is repeated here) and generates a warning. - */ - cpp_warning (pfile, - "VAX-C-style include specification found, use '#include ' !"); - angle_brackets = 1; - /* If -I-, start with the first -I dir after the -I-. */ - if (CPP_OPTIONS (pfile)->first_bracket_include) - search_start = CPP_OPTIONS (pfile)->first_bracket_include; - fbeg = pfile->token_buffer + old_written; - fend = CPP_PWRITTEN (pfile); - } -#endif - else - { - cpp_error (pfile, - "`#%s' expects \"FILENAME\" or ", keyword->name); - CPP_SET_WRITTEN (pfile, old_written); - skip_rest_of_line (pfile); - return 0; - } - - *fend = 0; - - token = get_directive_token (pfile); - if (token != CPP_VSPACE) - { - cpp_error (pfile, "junk at end of `#include'"); - while (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) - token = get_directive_token (pfile); - } - - /* For #include_next, skip in the search path - past the dir in which the containing file was found. */ - if (skip_dirs) - { - cpp_buffer *fp; - for (fp = CPP_BUFFER (pfile); fp != NULL; fp = CPP_PREV_BUFFER (fp)) - if (fp->fname != NULL) - { - /* fp->dir is null if the containing file was specified with - an absolute file name. In that case, don't skip anything. */ - if (fp->dir == SELF_DIR_DUMMY) - search_start = CPP_OPTIONS (pfile)->include; - else if (fp->dir) - search_start = fp->dir->next; - break; - } - } - - CPP_SET_WRITTEN (pfile, old_written); - - flen = fend - fbeg; - - if (flen == 0) - { - cpp_error (pfile, "empty file name in `#%s'", keyword->name); - return 0; - } - - /* Allocate this permanently, because it gets stored in the definitions - of macros. */ - fname = (char *) Safe_malloc (pfile->max_include_len + flen + 4); - /* + 2 above for slash and terminating null. */ - /* + 2 added for '.h' on VMS (to support '#include filename') */ - - /* If specified file name is absolute, just open it. */ - - if (*fbeg == '/') { - strncpy (fname, fbeg, flen); - fname[flen] = 0; - if (redundant_include_p (pfile, fname)) - return 0; - if (importing) - f = lookup_import (pfile, fname, NULL_PTR); - else - f = open_include_file (pfile, fname, NULL_PTR); - if (f == -2) - return 0; /* Already included this file */ - } else { - /* Search directory path, trying to open the file. - Copy each filename tried into FNAME. */ - - for (searchptr = search_start; searchptr; searchptr = searchptr->next) { - if (searchptr->fname) { - /* The empty string in a search path is ignored. - This makes it possible to turn off entirely - a standard piece of the list. */ - if (searchptr->fname[0] == 0) - continue; - strcpy (fname, searchptr->fname); - strcat (fname, "/"); - fname[strlen (fname) + flen] = 0; - } else { - fname[0] = 0; - } - strncat (fname, fbeg, flen); -#ifdef VMS - /* Change this 1/2 Unix 1/2 VMS file specification into a - full VMS file specification */ - if (searchptr->fname && (searchptr->fname[0] != 0)) { - /* Fix up the filename */ - hack_vms_include_specification (fname); - } else { - /* This is a normal VMS filespec, so use it unchanged. */ - strncpy (fname, fbeg, flen); - fname[flen] = 0; - /* if it's '#include filename', add the missing .h */ - if (index(fname,'.')==NULL) { - strcat (fname, ".h"); - } - } -#endif /* VMS */ - /* ??? There are currently 3 separate mechanisms for avoiding processing - of redundant include files: #import, #pragma once, and - redundant_include_p. It would be nice if they were unified. */ - if (redundant_include_p (pfile, fname)) - return 0; - if (importing) - f = lookup_import (pfile, fname, searchptr); - else - f = open_include_file (pfile, fname, searchptr); - if (f == -2) - return 0; /* Already included this file */ -#ifdef EACCES - else if (f == -1 && errno == EACCES) - cpp_warning (pfile, "Header file %s exists, but is not readable", - fname); -#endif - if (f >= 0) - break; - } - } - - if (f < 0) - { - /* A file that was not found. */ - strncpy (fname, fbeg, flen); - fname[flen] = 0; - /* If generating dependencies and -MG was specified, we assume missing - files are leaf files, living in the same directory as the source file - or other similar place; these missing files may be generated from - other files and may not exist yet (eg: y.tab.h). */ - - if (CPP_OPTIONS(pfile)->print_deps_missing_files - && CPP_PRINT_DEPS (pfile) - > (angle_brackets || (pfile->system_include_depth > 0))) - { - /* If it was requested as a system header file, - then assume it belongs in the first place to look for such. */ - if (angle_brackets) - { - for (searchptr = search_start; searchptr; - searchptr = searchptr->next) - { - if (searchptr->fname) - { - char *p; - - if (searchptr->fname[0] == 0) - continue; - p = (char *) alloca (strlen (searchptr->fname) - + strlen (fname) + 2); - strcpy (p, searchptr->fname); - strcat (p, "/"); - strcat (p, fname); - deps_output (pfile, p, ' '); - break; - } - } - } - else - { - /* Otherwise, omit the directory, as if the file existed - in the directory with the source. */ - deps_output (pfile, fname, ' '); - } - } - /* If -M was specified, and this header file won't be added to the - dependency list, then don't count this as an error, because we can - still produce correct output. Otherwise, we can't produce correct - output, because there may be dependencies we need inside the missing - file, and we don't know what directory this missing file exists in.*/ - else if (CPP_PRINT_DEPS (pfile) - && (CPP_PRINT_DEPS (pfile) - <= (angle_brackets || (pfile->system_include_depth > 0)))) - cpp_warning (pfile, "No include path in which to find %s", fname); - else if (search_start) - cpp_error_from_errno (pfile, fname); - else - cpp_error (pfile, "No include path in which to find %s", fname); - } - else { - /* Check to see if this include file is a once-only include file. - If so, give up. */ - - struct file_name_list* ptr; - - for (ptr = pfile->dont_repeat_files; ptr; ptr = ptr->next) { - if (!strcmp (ptr->fname, fname)) { - close (f); - return 0; /* This file was once'd. */ - } - } - - for (ptr = pfile->all_include_files; ptr; ptr = ptr->next) { - if (!strcmp (ptr->fname, fname)) - break; /* This file was included before. */ - } - - if (ptr == 0) { - /* This is the first time for this file. */ - /* Add it to list of files included. */ - - ptr = (struct file_name_list *) Safe_malloc (sizeof (struct file_name_list)); - ptr->control_macro = 0; - ptr->c_system_include_path = 0; - ptr->next = pfile->all_include_files; - pfile->all_include_files = ptr; - ptr->fname = savestring (fname); - ptr->got_name_map = 0; - - /* For -M, add this file to the dependencies. */ - if (CPP_PRINT_DEPS (pfile) - > (angle_brackets || (pfile->system_include_depth > 0))) - deps_output (pfile, fname, ' '); - } - - /* Handle -H option. */ - if (CPP_OPTIONS(pfile)->print_include_names) - { - cpp_buffer *buf = CPP_BUFFER (pfile); - while ((buf = CPP_PREV_BUFFER (buf)) != NULL) - putc ('.', stderr); - fprintf (stderr, "%s\n", fname); - } - - if (angle_brackets) - pfile->system_include_depth++; - - /* Actually process the file. */ - - /* Record file on "seen" list for #import. */ - add_import (pfile, f, fname); - - pcftry = (char *) alloca (strlen (fname) + 30); - pcfbuf = 0; - pcfnum = 0; - -#if 0 - if (!no_precomp) - { - struct stat stat_f; - - fstat (f, &stat_f); - - do { - sprintf (pcftry, "%s%d", fname, pcfnum++); - - pcf = open (pcftry, O_RDONLY, 0666); - if (pcf != -1) - { - struct stat s; - - fstat (pcf, &s); - if (bcmp ((char *) &stat_f.st_ino, (char *) &s.st_ino, - sizeof (s.st_ino)) - || stat_f.st_dev != s.st_dev) - { - pcfbuf = check_precompiled (pcf, fname, &pcfbuflimit); - /* Don't need it any more. */ - close (pcf); - } - else - { - /* Don't need it at all. */ - close (pcf); - break; - } - } - } while (pcf != -1 && !pcfbuf); - } -#endif - - /* Actually process the file */ - cpp_push_buffer (pfile, NULL, 0); - if (finclude (pfile, f, fname, is_system_include (pfile, fname), - searchptr != dsp ? searchptr : SELF_DIR_DUMMY)) - { - output_line_command (pfile, 0, enter_file); - pfile->only_seen_white = 2; - } - - if (angle_brackets) - pfile->system_include_depth--; - } - return 0; -} - -/* Return nonzero if there is no need to include file NAME - because it has already been included and it contains a conditional - to make a repeated include do nothing. */ - -static int -redundant_include_p ( - cpp_reader *pfile, - char *name) -{ - struct file_name_list *l = pfile->all_include_files; - for (; l; l = l->next) - if (! strcmp (name, l->fname) - && l->control_macro - && cpp_lookup (pfile, l->control_macro, -1, -1)) - return 1; - return 0; -} - -/* Return nonzero if the given FILENAME is an absolute pathname which - designates a file within one of the known "system" include file - directories. We assume here that if the given FILENAME looks like - it is the name of a file which resides either directly in a "system" - include file directory, or within any subdirectory thereof, then the - given file must be a "system" include file. This function tells us - if we should suppress pedantic errors/warnings for the given FILENAME. - - The value is 2 if the file is a C-language system header file - for which C++ should (on most systems) assume `extern "C"'. */ - -static int -is_system_include ( - cpp_reader *pfile, - register char *filename) -{ - struct file_name_list *searchptr; - - for (searchptr = CPP_OPTIONS (pfile)->first_system_include; searchptr; - searchptr = searchptr->next) - if (searchptr->fname) { - register char *sys_dir = searchptr->fname; - register unsigned length = strlen (sys_dir); - - if (! strncmp (sys_dir, filename, length) && filename[length] == '/') - { - if (searchptr->c_system_include_path) - return 2; - else - return 1; - } - } - return 0; -} - - -/* - * Install a name in the assertion hash table. - * - * If LEN is >= 0, it is the length of the name. - * Otherwise, compute the length by scanning the entire name. - * - * If HASH is >= 0, it is the precomputed hash code. - * Otherwise, compute the hash code. - */ -static ASSERTION_HASHNODE * -assertion_install ( - cpp_reader *pfile, - U_CHAR *name, - int len, - int hash) -{ - register ASSERTION_HASHNODE *hp; - register int i, bucket; - register U_CHAR *p, *q; - - i = sizeof (ASSERTION_HASHNODE) + len + 1; - hp = (ASSERTION_HASHNODE *) Safe_malloc (i); - bucket = hash; - hp->bucket_hdr = &pfile->assertion_hashtab[bucket]; - hp->next = pfile->assertion_hashtab[bucket]; - pfile->assertion_hashtab[bucket] = hp; - hp->prev = NULL; - if (hp->next != NULL) - hp->next->prev = hp; - hp->length = len; - hp->value = 0; - hp->name = ((U_CHAR *) hp) + sizeof (ASSERTION_HASHNODE); - p = hp->name; - q = name; - for (i = 0; i < len; i++) - *p++ = *q++; - hp->name[len] = 0; - return hp; -} -/* - * find the most recent hash node for name name (ending with first - * non-identifier char) installed by install - * - * If LEN is >= 0, it is the length of the name. - * Otherwise, compute the length by scanning the entire name. - * - * If HASH is >= 0, it is the precomputed hash code. - * Otherwise, compute the hash code. - */ - -static ASSERTION_HASHNODE * -assertion_lookup ( - cpp_reader *pfile, - U_CHAR *name, - int len, - int hash) -{ - register ASSERTION_HASHNODE *bucket; - - bucket = pfile->assertion_hashtab[hash]; - while (bucket) { - if (bucket->length == len && strncmp (bucket->name, name, len) == 0) - return bucket; - bucket = bucket->next; - } - return NULL; -} - -static void -delete_assertion ( - ASSERTION_HASHNODE *hp) -{ - struct tokenlist_list *tail; - if (hp->prev != NULL) - hp->prev->next = hp->next; - if (hp->next != NULL) - hp->next->prev = hp->prev; - - for (tail = hp->value; tail; ) - { - struct tokenlist_list *next = tail->next; - free_token_list (tail->tokens); - Safe_free (tail); - tail = next; - } - - /* make sure that the bucket chain header that - the deleted guy was on points to the right thing afterwards. */ - if (hp == *hp->bucket_hdr) - *hp->bucket_hdr = hp->next; - - Safe_free (hp); -} - -/* Convert a character string literal into a nul-terminated string. - The input string is [IN ... LIMIT). - The result is placed in RESULT. RESULT can be the same as IN. - The value returned in the end of the string written to RESULT, - or NULL on error. */ - -static U_CHAR* -convert_string ( - cpp_reader *pfile, - register U_CHAR *result, U_CHAR *in,U_CHAR *limit, - int handle_escapes) -{ - U_CHAR c; - c = *in++; - if (c != '\"') - return NULL; - while (in < limit) - { - U_CHAR c = *in++; - switch (c) - { - case '\0': - return NULL; - case '\"': - limit = in; - break; - case '\\': - if (handle_escapes) - { - char *bpc = (char *) in; - int i = (U_CHAR) cpp_parse_escape (pfile, &bpc); - in = (U_CHAR *) bpc; - if (i >= 0) - *result++ = (U_CHAR)c; - break; - } - /* else fall through */ - default: - *result++ = c; - } - } - *result = 0; - return result; -} - -/* - * interpret #line command. Remembers previously seen fnames - * in its very own hash table. - */ -#define FNAME_HASHSIZE 37 - -static int -do_line ( - cpp_reader *pfile, - struct directive *keyword) -{ - cpp_buffer *ip = CPP_BUFFER (pfile); - int new_lineno; - long old_written = CPP_WRITTEN (pfile); - enum file_change_code file_change = same_file; - enum cpp_token token; -/* int i;*/ - - token = get_directive_token (pfile); - - if (token != CPP_NUMBER - || !isdigit(pfile->token_buffer[old_written])) - { - cpp_error (pfile, "invalid format `#line' command"); - goto bad_line_directive; - } - - /* The Newline at the end of this line remains to be processed. - To put the next line at the specified line number, - we must store a line number now that is one less. */ - new_lineno = atoi (pfile->token_buffer + old_written) - 1; - CPP_SET_WRITTEN (pfile, old_written); - - /* NEW_LINENO is one less than the actual line number here. */ - if (CPP_PEDANTIC (pfile) && new_lineno < 0) - cpp_pedwarn (pfile, "line number out of range in `#line' command"); - -#if 0 /* #line 10"foo.c" is supposed to be allowed. */ - if (PEEKC() && !is_space[PEEKC()]) { - cpp_error (pfile, "invalid format `#line' command"); - goto bad_line_directive; - } -#endif - - token = get_directive_token (pfile); - - if (token == CPP_STRING) { - U_CHAR *fname = pfile->token_buffer + old_written; - U_CHAR *end_name; - static HASHNODE *fname_table[FNAME_HASHSIZE]; - HASHNODE *hp, **hash_bucket; - U_CHAR *p; - long num_start; - int fname_length; - - /* Turn the file name, which is a character string literal, - into a null-terminated string. Do this in place. */ - end_name = convert_string (pfile, fname, fname, CPP_PWRITTEN (pfile), 1); - if (end_name == NULL) - { - cpp_error (pfile, "invalid format `#line' command"); - goto bad_line_directive; - } - - fname_length = end_name - fname; - - num_start = CPP_WRITTEN (pfile); - token = get_directive_token (pfile); - if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) { - p = pfile->token_buffer + num_start; - if (CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "garbage at end of `#line' command"); - - if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0') - { - cpp_error (pfile, "invalid format `#line' command"); - goto bad_line_directive; - } - if (*p == '1') - file_change = enter_file; - else if (*p == 2) - file_change = leave_file; - else if (*p == 3) - ip->system_header_p = 1; - else /* if (*p == 4) */ - ip->system_header_p = 2; - - CPP_SET_WRITTEN (pfile, num_start); - token = get_directive_token (pfile); - p = pfile->token_buffer + num_start; - if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4')) { - ip->system_header_p = *p == 3 ? 1 : 2; - token = get_directive_token (pfile); - } - if (token != CPP_VSPACE) { - cpp_error (pfile, "invalid format `#line' command"); - goto bad_line_directive; - } - } - - hash_bucket = - &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)]; - for (hp = *hash_bucket; hp != NULL; hp = hp->next) - if (hp->length == fname_length && - strncmp (hp->value.cpval, fname, fname_length) == 0) { - ip->nominal_fname = hp->value.cpval; - break; - } - if (hp == 0) { - /* Didn't find it; cons up a new one. */ - hp = (HASHNODE *) Safe_calloc(1,sizeof (HASHNODE) + fname_length + 1); - hp->next = *hash_bucket; - *hash_bucket = hp; - - hp->length = fname_length; - ip->nominal_fname = hp->value.cpval = ((char *) hp) + sizeof (HASHNODE); - bcopy (fname, hp->value.cpval, fname_length); - } - } - else if (token != CPP_VSPACE && token != CPP_EOF) { - cpp_error (pfile, "invalid format `#line' command"); - goto bad_line_directive; - } - - ip->lineno = new_lineno; - bad_line_directive: - skip_rest_of_line (pfile); - CPP_SET_WRITTEN (pfile, old_written); - output_line_command (pfile, 0, file_change); - return 0; -} - -/* - * remove the definition of a symbol from the symbol table. - * according to un*x /lib/cpp, it is not an error to undef - * something that has no definitions, so it isn't one here either. - */ - -static int -do_undef ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *buf, U_CHAR *limit) -{ - int sym_length; - HASHNODE *hp; - U_CHAR *orig_buf = buf; - -#if 0 - /* If this is a precompiler run (with -pcp) pass thru #undef commands. */ - if (pcp_outfile && keyword) - pass_thru_directive (buf, limit, pfile, keyword); -#endif - - SKIP_WHITE_SPACE (buf); - sym_length = check_macro_name (pfile, buf, "macro"); - - while ((hp = cpp_lookup (pfile, buf, sym_length, -1)) != NULL) - { - /* If we are generating additional info for debugging (with -g) we - need to pass through all effective #undef commands. */ - if (CPP_OPTIONS (pfile)->debug_output && keyword) - pass_thru_directive (orig_buf, limit, pfile, keyword); - if (hp->type != T_MACRO) - cpp_warning (pfile, "undefining `%s'", hp->name); - delete_macro (hp); - } - - if (CPP_PEDANTIC (pfile)) { - buf += sym_length; - SKIP_WHITE_SPACE (buf); - if (buf != limit) - cpp_pedwarn (pfile, "garbage after `#undef' directive"); - } - return 0; -} - -/* - * Report an error detected by the program we are processing. - * Use the text of the line in the error message. - * (We use error because it prints the filename & line#.) - */ - -static int -do_error ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *buf,U_CHAR *limit) -{ - int length = limit - buf; - U_CHAR *copy = (U_CHAR *) Safe_malloc (length + 1); - bcopy (buf, copy, length); - copy[length] = 0; - SKIP_WHITE_SPACE (copy); - cpp_error (pfile, "#error %s", copy); - return 0; -} - -/* - * Report a warning detected by the program we are processing. - * Use the text of the line in the warning message, then continue. - * (We use error because it prints the filename & line#.) - */ - -static int -do_warning ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *buf,U_CHAR *limit) -{ - int length = limit - buf; - U_CHAR *copy = (U_CHAR *) Safe_malloc (length + 1); - bcopy (buf, copy, length); - copy[length] = 0; - SKIP_WHITE_SPACE (copy); - cpp_warning (pfile, "#warning %s", copy); - return 0; -} - -/* Remember the name of the current file being read from so that we can - avoid ever including it again. */ - -static int -do_once ( - cpp_reader *pfile) -{ - cpp_buffer *ip = NULL; - struct file_name_list *new; - - for (ip = CPP_BUFFER (pfile); ; ip = CPP_PREV_BUFFER (ip)) - { - if (ip == NULL) - return 0; - if (ip->fname != NULL) - break; - } - - - new = (struct file_name_list *) Safe_malloc (sizeof (struct file_name_list)); - new->next = pfile->dont_repeat_files; - pfile->dont_repeat_files = new; - new->fname = savestring (ip->fname); - new->control_macro = 0; - new->got_name_map = 0; - new->c_system_include_path = 0; - - return 0; -} - -/* #ident has already been copied to the output file, so just ignore it. */ - -static int -do_ident ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *buf, U_CHAR *limit) -{ -/* long old_written = CPP_WRITTEN (pfile);*/ -/* int len;*/ - - /* Allow #ident in system headers, since that's not user's fault. */ - if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p) - cpp_pedwarn (pfile, "ANSI C does not allow `#ident'"); - - /* Leave rest of line to be read by later calls to cpp_get_token. */ - - return 0; -} - -/* #pragma and its argument line have already been copied to the output file. - Just check for some recognized pragmas that need validation here. */ - -static int -do_pragma ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *buf,U_CHAR *limit) -{ - while (*buf == ' ' || *buf == '\t') - buf++; - if (!strncmp (buf, "once", 4)) { - /* Allow #pragma once in system headers, since that's not the user's - fault. */ - if (!CPP_BUFFER (pfile)->system_header_p) - cpp_warning (pfile, "`#pragma once' is obsolete"); - do_once (pfile); - } - - if (!strncmp (buf, "implementation", 14)) { - /* Be quiet about `#pragma implementation' for a file only if it hasn't - been included yet. */ - struct file_name_list *ptr; - U_CHAR *p = buf + 14, *fname, *inc_fname; - int fname_len; - SKIP_WHITE_SPACE (p); - if (*p == '\n' || *p != '\"') - return 0; - - fname = p + 1; - p = (U_CHAR *) index (fname, '\"'); - fname_len = p != NULL ? p - fname : strlen (fname); - - for (ptr = pfile->all_include_files; ptr; ptr = ptr->next) { - inc_fname = (U_CHAR *) rindex (ptr->fname, '/'); - inc_fname = inc_fname ? inc_fname + 1 : (U_CHAR *) ptr->fname; - if (inc_fname && !strncmp (inc_fname, fname, fname_len)) - cpp_warning (pfile, - "`#pragma implementation' for `%s' appears after file is included", - fname); - } - } - - return 0; -} - -#if 0 -/* This was a fun hack, but #pragma seems to start to be useful. - By failing to recognize it, we pass it through unchanged to cc1. */ - -/* - * the behavior of the #pragma directive is implementation defined. - * this implementation defines it as follows. - */ - -static int -do_pragma () -{ - close (0); - if (open ("/dev/tty", O_RDONLY, 0666) != 0) - goto nope; - close (1); - if (open ("/dev/tty", O_WRONLY, 0666) != 1) - goto nope; - execl ("/usr/games/hack", "#pragma", 0); - execl ("/usr/games/rogue", "#pragma", 0); - execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0); - execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0); -nope: - fatal ("You are in a maze of twisty compiler features, all different"); -} -#endif - -/* Just ignore #sccs, on systems where we define it at all. */ - -static int -do_sccs ( - cpp_reader *pfile , - struct directive *keyword, - U_CHAR *buf,U_CHAR *limit) -{ - if (CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "ANSI C does not allow `#sccs'"); - return 0; -} - -/* - * handle #if command by - * 1) inserting special `defined' keyword into the hash table - * that gets turned into 0 or 1 by special_symbol (thus, - * if the luser has a symbol called `defined' already, it won't - * work inside the #if command) - * 2) rescan the input into a temporary output buffer - * 3) pass the output buffer to the yacc parser and collect a value - * 4) clean up the mess left from steps 1 and 2. - * 5) call conditional_skip to skip til the next #endif (etc.), - * or not, depending on the value from step 3. - */ - -static int -do_if ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *buf,U_CHAR *limit) -{ - HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf); - conditional_skip (pfile, value == 0, T_IF, NULL_PTR); - return 0; -} - -/* - * handle a #elif directive by not changing if_stack either. - * see the comment above do_else. - */ - -static int -do_elif ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *buf,U_CHAR *limit) -{ - if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack) { - cpp_error (pfile, "`#elif' not within a conditional"); - return 0; - } else { - if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF) { - cpp_error (pfile, "`#elif' after `#else'"); -#if 0 - fprintf (stderr, " (matches line %d", pfile->if_stack->lineno); -#endif - if (pfile->if_stack->fname != NULL && CPP_BUFFER (pfile)->fname != NULL - && strcmp (pfile->if_stack->fname, - CPP_BUFFER (pfile)->nominal_fname) != 0) - fprintf (stderr, ", file %s", pfile->if_stack->fname); - fprintf (stderr, ")\n"); - } - pfile->if_stack->type = T_ELIF; - } - - if (pfile->if_stack->if_succeeded) - skip_if_group (pfile, 0); - else { - HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf); - if (value == 0) - skip_if_group (pfile, 0); - else { - ++pfile->if_stack->if_succeeded; /* continue processing input */ - output_line_command (pfile, 1, same_file); - } - } - return 0; -} - -/* - * evaluate a #if expression in BUF, of length LENGTH, - * then parse the result as a C expression and return the value as an int. - */ -static HOST_WIDE_INT -eval_if_expression ( - cpp_reader *pfile, - U_CHAR *buf, - int length) -{ - HASHNODE *save_defined; - HOST_WIDE_INT value; - long old_written = CPP_WRITTEN (pfile); - - save_defined = install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1); - pfile->pcp_inside_if = 1; - - value = cpp_parse_expr (pfile); - pfile->pcp_inside_if = 0; - delete_macro (save_defined); /* clean up special symbol */ - - CPP_SET_WRITTEN (pfile, old_written); /* Pop */ - - return value; -} - -/* - * routine to handle ifdef/ifndef. Try to look up the symbol, - * then do or don't skip to the #endif/#else/#elif depending - * on what directive is actually being processed. - */ - -static int -do_xifdef ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *unused1, U_CHAR *unused2) -{ - int skip; - cpp_buffer *ip = CPP_BUFFER (pfile); - U_CHAR* ident; - int ident_length; - enum cpp_token token; - int start_of_file = 0; - U_CHAR *control_macro = 0; - int old_written = CPP_WRITTEN (pfile); - - /* Detect a #ifndef at start of file (not counting comments). */ - if (ip->fname != 0 && keyword->type == T_IFNDEF) - start_of_file = pfile->only_seen_white == 2; - - pfile->no_macro_expand++; - token = get_directive_token (pfile); - pfile->no_macro_expand--; - - ident = pfile->token_buffer + old_written; - ident_length = CPP_WRITTEN (pfile) - old_written; - CPP_SET_WRITTEN (pfile, old_written); /* Pop */ - - if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF) - { - skip = (keyword->type == T_IFDEF); - if (! CPP_TRADITIONAL (pfile)) - cpp_pedwarn (pfile, "`#%s' with no argument", keyword->name); - } - else if (token == CPP_NAME) - { - HASHNODE *hp = cpp_lookup (pfile, ident, ident_length, -1); - skip = (hp == NULL) ^ (keyword->type == T_IFNDEF); - if (start_of_file && !skip) - { - control_macro = (U_CHAR *) Safe_malloc (ident_length + 1); - bcopy (ident, control_macro, ident_length + 1); - } - } - else - { - skip = (keyword->type == T_IFDEF); - if (! CPP_TRADITIONAL (pfile)) - cpp_error (pfile, "`#%s' with invalid argument", keyword->name); - } - - if (!CPP_TRADITIONAL (pfile)) - { int c; - cpp_skip_hspace (pfile); - c = PEEKC (); - if (c != EOF && c != '\n') - cpp_pedwarn (pfile, "garbage at end of `#%s' argument", keyword->name); - } - skip_rest_of_line (pfile); - -#if 0 - if (pcp_outfile) { - /* Output a precondition for this macro. */ - if (hp && hp->value.defn->predefined) - fprintf (pcp_outfile, "#define %s\n", hp->name); - else { - U_CHAR *cp = buf; - fprintf (pcp_outfile, "#undef "); - while (is_idchar[*cp]) /* Ick! */ - fputc (*cp++, pcp_outfile); - putc ('\n', pcp_outfile); - } -#endif - - conditional_skip (pfile, skip, T_IF, control_macro); - return 0; -} - -/* Push TYPE on stack; then, if SKIP is nonzero, skip ahead. - If this is a #ifndef starting at the beginning of a file, - CONTROL_MACRO is the macro name tested by the #ifndef. - Otherwise, CONTROL_MACRO is 0. */ - -static void -conditional_skip ( - cpp_reader *pfile, - int skip, - enum node_type type, - U_CHAR *control_macro) -{ - IF_STACK_FRAME *temp; - - temp = (IF_STACK_FRAME *) Safe_calloc(1,sizeof (IF_STACK_FRAME)); - temp->fname = CPP_BUFFER (pfile)->nominal_fname; -#if 0 - temp->lineno = CPP_BUFFER (pfile)->lineno; -#endif - temp->next = pfile->if_stack; - temp->control_macro = control_macro; - pfile->if_stack = temp; - - pfile->if_stack->type = type; - - if (skip != 0) { - skip_if_group (pfile, 0); - return; - } else { - ++pfile->if_stack->if_succeeded; - output_line_command (pfile, 1, same_file); - } -} - -/* - * skip to #endif, #else, or #elif. adjust line numbers, etc. - * leaves input ptr at the sharp sign found. - * If ANY is nonzero, return at next directive of any sort. - */ -static void -skip_if_group ( - cpp_reader *pfile, - int any) -{ - int c; - struct directive *kt; - IF_STACK_FRAME *save_if_stack = pfile->if_stack; /* don't pop past here */ -#if 0 - U_CHAR *beg_of_line = bp; -#endif - register int ident_length; - U_CHAR *ident /*, *after_ident */ ; - struct parse_marker line_start_mark; - - parse_set_mark (&line_start_mark, pfile); - - if (CPP_OPTIONS (pfile)->output_conditionals) { - static char failed[] = "#failed\n"; - CPP_PUTS (pfile, failed, sizeof(failed)-1); - pfile->lineno++; - output_line_command (pfile, 1, same_file); - } - - beg_of_line: - if (CPP_OPTIONS (pfile)->output_conditionals) - { - cpp_buffer *pbuf = CPP_BUFFER (pfile); - U_CHAR *start_line = pbuf->buf + line_start_mark.position; - CPP_PUTS (pfile, start_line, pbuf->cur - start_line); - } - parse_move_mark (&line_start_mark, pfile); - if (!CPP_TRADITIONAL (pfile)) - cpp_skip_hspace (pfile); - c = GETC(); - if (c == '#') - { - int old_written = CPP_WRITTEN (pfile); - cpp_skip_hspace (pfile); - - parse_name (pfile, GETC()); - ident_length = CPP_WRITTEN (pfile) - old_written; - ident = pfile->token_buffer + old_written; - pfile->limit = ident; -#if 0 - if (ident_length == 0) - goto not_a_directive; - - /* Handle # followed by a line number. */ - - /* Avoid error for `###' and similar cases unless -pedantic. */ -#endif - - for (kt = directive_table; kt->length >= 0; kt++) - { - IF_STACK_FRAME *temp; - if (ident_length == kt->length - && strncmp (ident, kt->name, kt->length) == 0) - { - /* If we are asked to return on next directive, do so now. */ - if (any) - goto done; - - switch (kt->type) - { - case T_IF: - case T_IFDEF: - case T_IFNDEF: - temp - = (IF_STACK_FRAME *) Safe_calloc(1,sizeof (IF_STACK_FRAME)); - temp->next = pfile->if_stack; - pfile->if_stack = temp; -#if 0 - temp->lineno = CPP_BUFFER(pfile)->lineno; -#endif - temp->fname = CPP_BUFFER(pfile)->nominal_fname; - temp->type = kt->type; - break; - case T_ELSE: - case T_ENDIF: - if (CPP_PEDANTIC (pfile) && pfile->if_stack != save_if_stack) - validate_else (pfile, - kt->type == T_ELSE ? "#else" : "#endif"); - case T_ELIF: - if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack) - { - cpp_error (pfile, - "`#%s' not within a conditional", kt->name); - break; - } - else if (pfile->if_stack == save_if_stack) - goto done; /* found what we came for */ - - if (kt->type != T_ENDIF) - { - if (pfile->if_stack->type == T_ELSE) - cpp_error (pfile, "`#else' or `#elif' after `#else'"); - pfile->if_stack->type = kt->type; - break; - } - - temp = pfile->if_stack; - pfile->if_stack = temp->next; - Safe_free (temp); - break; - default: ; - } - break; - } - /* Don't let erroneous code go by. */ - if (kt->length < 0 && !CPP_OPTIONS (pfile)->lang_asm - && CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "invalid preprocessor directive name"); - } - c = GETC (); - } - /* We're in the middle of a line. Skip the rest of it. */ - for (;;) { - switch (c) - { - long old; - case EOF: - goto done; - case '/': /* possible comment */ - c = skip_comment (pfile, NULL); - if (c == EOF) - goto done; - break; - case '\"': - case '\'': - FORWARD(-1); - old = CPP_WRITTEN (pfile); - cpp_get_token (pfile); - CPP_SET_WRITTEN (pfile, old); - break; - case '\\': - /* Char after backslash loses its special meaning. */ - if (PEEKC() == '\n') - FORWARD (1); - break; - case '\n': - goto beg_of_line; - break; - } - c = GETC (); - } - done: - if (CPP_OPTIONS (pfile)->output_conditionals) { - static char end_failed[] = "#endfailed\n"; - CPP_PUTS (pfile, end_failed, sizeof(end_failed)-1); - pfile->lineno++; - } - pfile->only_seen_white = 1; - parse_goto_mark (&line_start_mark, pfile); - parse_clear_mark (&line_start_mark); -} - -/* - * handle a #else directive. Do this by just continuing processing - * without changing if_stack ; this is so that the error message - * for missing #endif's etc. will point to the original #if. It - * is possible that something different would be better. - */ - -static int -do_else ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *buf, U_CHAR *limit) -{ - cpp_buffer *ip = CPP_BUFFER (pfile); - - if (CPP_PEDANTIC (pfile)) - validate_else (pfile, "#else"); - skip_rest_of_line (pfile); - - if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack) { - cpp_error (pfile, "`#else' not within a conditional"); - return 0; - } else { - /* #ifndef can't have its special treatment for containing the whole file - if it has a #else clause. */ - pfile->if_stack->control_macro = 0; - - if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF) { - cpp_error (pfile, "`#else' after `#else'"); - fprintf (stderr, " (matches line %d", pfile->if_stack->lineno); - if (strcmp (pfile->if_stack->fname, ip->nominal_fname) != 0) - fprintf (stderr, ", file %s", pfile->if_stack->fname); - fprintf (stderr, ")\n"); - } - pfile->if_stack->type = T_ELSE; - } - - if (pfile->if_stack->if_succeeded) - skip_if_group (pfile, 0); - else { - ++pfile->if_stack->if_succeeded; /* continue processing input */ - output_line_command (pfile, 1, same_file); - } - return 0; -} - -/* - * unstack after #endif command - */ - -static int -do_endif ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *buf, U_CHAR *limit) -{ - if (CPP_PEDANTIC (pfile)) - validate_else (pfile, "#endif"); - skip_rest_of_line (pfile); - - if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack) - cpp_error (pfile, "unbalanced `#endif'"); - else - { - IF_STACK_FRAME *temp = pfile->if_stack; - pfile->if_stack = temp->next; - if (temp->control_macro != 0) - { - /* This #endif matched a #ifndef at the start of the file. - See if it is at the end of the file. */ - struct parse_marker start_mark; - int c; - - parse_set_mark (&start_mark, pfile); - - for (;;) - { - cpp_skip_hspace (pfile); - c = GETC (); - if (c != '\n') - break; - } - parse_goto_mark (&start_mark, pfile); - parse_clear_mark (&start_mark); - - if (c == EOF) - { - /* If we get here, this #endif ends a #ifndef - that contains all of the file (aside from whitespace). - Arrange not to include the file again - if the macro that was tested is defined. - - Do not do this for the top-level file in a -include or any - file in a -imacros. */ -#if 0 -FIXME! - if (indepth != 0 - && ! (indepth == 1 && pfile->no_record_file) - && ! (pfile->no_record_file && no_output)) -#endif - { - struct file_name_list *ifile = pfile->all_include_files; - - for ( ; ifile != NULL; ifile = ifile->next) - { - if (!strcmp (ifile->fname, CPP_BUFFER (pfile)->fname)) - { - ifile->control_macro = temp->control_macro; - break; - } - } - } - } - } - Safe_free (temp); - output_line_command (pfile, 1, same_file); - } - return 0; -} - -/* When an #else or #endif is found while skipping failed conditional, - if -pedantic was specified, this is called to warn about text after - the command name. P points to the first char after the command name. */ - -static void -validate_else ( - cpp_reader *pfile, - char *directive) -{ - int c; - cpp_skip_hspace (pfile); - c = PEEKC (); - if (c != EOF && c != '\n') - cpp_pedwarn (pfile, - "text following `%s' violates ANSI standard", directive); -} - -/* Get the next token, and add it to the text in pfile->token_buffer. - Return the kind of token we got. */ - - -enum cpp_token -cpp_get_token ( - cpp_reader *pfile) -{ - register int c, c2, c3; - long old_written = 0; - long start_line, start_column; - enum cpp_token token; - struct cpp_options *opts = CPP_OPTIONS (pfile); - CPP_BUFFER (pfile)->prev = CPP_BUFFER (pfile)->cur; - get_next: - c = GETC(); - if (c == EOF) - { - handle_eof: - if (CPP_BUFFER (pfile)->seen_eof) - { - if (cpp_pop_buffer (pfile) != CPP_NULL_BUFFER (pfile)) - goto get_next; - else - return CPP_EOF; - } - else - { - cpp_buffer *next_buf - = CPP_PREV_BUFFER (CPP_BUFFER (pfile)); - CPP_BUFFER (pfile)->seen_eof = 1; - if (CPP_BUFFER (pfile)->nominal_fname && next_buf != 0) - { - /* We're about to return from an #include file. - Emit #line information now (as part of the CPP_POP) result. - But the #line refers to the file we will pop to. */ - cpp_buffer *cur_buffer = CPP_BUFFER (pfile); - CPP_BUFFER (pfile) = next_buf; - pfile->input_stack_listing_current = 0; - output_line_command (pfile, 0, leave_file); - CPP_BUFFER (pfile) = cur_buffer; - } - return CPP_POP; - } - } - else - { - switch (c) - { - long newlines; - struct parse_marker start_mark; - case '/': - if (PEEKC () == '=') - goto op2; - if (opts->put_out_comments) - parse_set_mark (&start_mark, pfile); - newlines = 0; - cpp_buf_line_and_col (cpp_file_buffer (pfile), - &start_line, &start_column); - c = skip_comment (pfile, &newlines); - if (opts->put_out_comments && (c == '/' || c == EOF)) - parse_clear_mark (&start_mark); - if (c == '/') - goto randomchar; - if (c == EOF) - { - cpp_error_with_line (pfile, start_line, start_column, - "unterminated comment"); - goto handle_eof; - } - c = '/'; /* Initial letter of comment. */ - return_comment: - /* Comments are equivalent to spaces. - For -traditional, a comment is equivalent to nothing. */ - if (opts->put_out_comments) - { - cpp_buffer *pbuf = CPP_BUFFER (pfile); - /* long dummy; */ - U_CHAR *start = pbuf->buf + start_mark.position; - int len = pbuf->cur - start; - CPP_RESERVE(pfile, 1 + len); - CPP_PUTC_Q (pfile, c); - CPP_PUTS_Q (pfile, start, len); - pfile->lineno += newlines; - parse_clear_mark (&start_mark); - return CPP_COMMENT; - } - else if (CPP_TRADITIONAL (pfile)) - { - return CPP_COMMENT; - } - else - { -#if 0 - /* This may not work if cpp_get_token is called recursively, - since many places look for horizontal space. */ - if (newlines) - { - /* Copy the newlines into the output buffer, in order to - avoid the pain of a #line every time a multiline comment - is seen. */ - CPP_RESERVE(pfile, newlines); - while (--newlines >= 0) - { - CPP_PUTC_Q (pfile, '\n'); - pfile->lineno++; - } - return CPP_VSPACE; - } -#endif - CPP_RESERVE(pfile, 1); - CPP_PUTC_Q (pfile, ' '); - return CPP_HSPACE; - } -#if 0 - if (opts->for_lint) { - U_CHAR *argbp; - int cmdlen, arglen; - char *lintcmd = get_lintcmd (ibp, limit, &argbp, &arglen, &cmdlen); - - if (lintcmd != NULL) { - /* I believe it is always safe to emit this newline: */ - obp[-1] = '\n'; - bcopy ("#pragma lint ", (char *) obp, 13); - obp += 13; - bcopy (lintcmd, (char *) obp, cmdlen); - obp += cmdlen; - - if (arglen != 0) { - *(obp++) = ' '; - bcopy (argbp, (char *) obp, arglen); - obp += arglen; - } - - /* OK, now bring us back to the state we were in before we entered - this branch. We need #line b/c the newline for the pragma - could fuck things up. */ - output_line_command (pfile, 0, same_file); - *(obp++) = ' '; /* just in case, if comments are copied thru */ - *(obp++) = '/'; - } - } -#endif - - case '#': -#if 0 - /* If this is expanding a macro definition, don't recognize - preprocessor directives. */ - if (ip->macro != 0) - goto randomchar; - /* If this is expand_into_temp_buffer, recognize them - only after an actual newline at this level, - not at the beginning of the input level. */ - if (ip->fname == 0 && beg_of_line == ip->buf) - goto randomchar; - if (ident_length) - goto specialchar; -#endif - - if (!pfile->only_seen_white) - goto randomchar; - if (handle_directive (pfile)) - return CPP_DIRECTIVE; - pfile->only_seen_white = 0; - return CPP_OTHER; - - case '\"': - case '\'': - /* A single quoted string is treated like a double -- some - programs (e.g., troff) are perverse this way */ - cpp_buf_line_and_col (cpp_file_buffer (pfile), - &start_line, &start_column); - old_written = CPP_WRITTEN (pfile); - string: - CPP_PUTC (pfile, c); - while (1) - { - int cc = GETC(); - if (cc == EOF) - { - if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) - { - /* try harder: this string crosses a macro expansion - boundary. This can happen naturally if -traditional. - Otherwise, only -D can make a macro with an unmatched - quote. */ - cpp_buffer *next_buf - = CPP_PREV_BUFFER (CPP_BUFFER (pfile)); - (*CPP_BUFFER (pfile)->cleanup) - (CPP_BUFFER (pfile), pfile); - CPP_BUFFER (pfile) = next_buf; - continue; - } - if (!CPP_TRADITIONAL (pfile)) - { - cpp_error_with_line (pfile, start_line, start_column, - "unterminated string or character constant"); - if (pfile->multiline_string_line != start_line - && pfile->multiline_string_line != 0) - cpp_error_with_line (pfile, - pfile->multiline_string_line, -1, - "possible real start of unterminated constant"); - pfile->multiline_string_line = 0; - } - break; - } - CPP_PUTC (pfile, cc); - switch (cc) - { - case '\n': - /* Traditionally, end of line ends a string constant with - no error. So exit the loop and record the new line. */ - if (CPP_TRADITIONAL (pfile)) - goto while2end; - if (c == '\'') - { - cpp_error_with_line (pfile, start_line, start_column, - "unterminated character constant"); - goto while2end; - } - if (CPP_PEDANTIC (pfile) - && pfile->multiline_string_line == 0) - { - cpp_pedwarn_with_line (pfile, start_line, start_column, - "string constant runs past end of line"); - } - if (pfile->multiline_string_line == 0) - pfile->multiline_string_line = start_line; - break; - - case '\\': - cc = GETC(); - if (cc == '\n') - { - /* Backslash newline is replaced by nothing at all. */ - CPP_ADJUST_WRITTEN (pfile, -1); - pfile->lineno++; - } - else - { - /* ANSI stupidly requires that in \\ the second \ - is *not* prevented from combining with a newline. */ - NEWLINE_FIX1(cc); - if (cc != EOF) - CPP_PUTC (pfile, cc); - } - break; - - case '\"': - case '\'': - if (cc == c) - goto while2end; - break; - } - } - while2end: - pfile->lineno += count_newlines (pfile->token_buffer + old_written, - CPP_PWRITTEN (pfile)); - pfile->only_seen_white = 0; - return c == '\'' ? CPP_CHAR : CPP_STRING; - - case '$': - if (!opts->dollars_in_ident) - goto randomchar; - goto letter; - - case ':': - if (opts->cplusplus && PEEKC () == ':') - goto op2; - goto randomchar; - - case '&': - case '+': - case '|': - NEWLINE_FIX; - c2 = PEEKC (); - if (c2 == c || c2 == '=') - goto op2; - goto randomchar; - - case '*': - case '!': - case '%': - case '=': - case '^': - NEWLINE_FIX; - if (PEEKC () == '=') - goto op2; - goto randomchar; - - case '-': - NEWLINE_FIX; - c2 = PEEKC (); - if (c2 == '-' && opts->chill) - { - /* Chill style comment */ - if (opts->put_out_comments) - parse_set_mark (&start_mark, pfile); - FORWARD(1); /* Skip second '-'. */ - for (;;) - { - c = GETC (); - if (c == EOF) - break; - if (c == '\n') - { - /* Don't consider final '\n' to be part of comment. */ - FORWARD(-1); - break; - } - } - c = '-'; - goto return_comment; - } - if (c2 == '-' || c2 == '=' || c2 == '>') - goto op2; - goto randomchar; - - case '<': - if (pfile->parsing_include_directive) - { - for (;;) - { - CPP_PUTC (pfile, c); - if (c == '>') - break; - c = GETC (); - NEWLINE_FIX1 (c); - if (c == '\n' || c == EOF) - { - cpp_error (pfile, - "missing '>' in `#include '"); - break; - } - } - return CPP_STRING; - } - /* else fall through */ - case '>': - NEWLINE_FIX; - c2 = PEEKC (); - if (c2 == '=') - goto op2; - if (c2 != c) - goto randomchar; - FORWARD(1); - CPP_RESERVE (pfile, 4); - CPP_PUTC (pfile, c); - CPP_PUTC (pfile, c2); - NEWLINE_FIX; - c3 = PEEKC (); - if (c3 == '=') - CPP_PUTC_Q (pfile, GETC ()); - CPP_NUL_TERMINATE_Q (pfile); - pfile->only_seen_white = 0; - return CPP_OTHER; - - case '@': - if (CPP_BUFFER (pfile)->has_escapes) - { - c = GETC (); - if (c == '-') - { - if (pfile->output_escapes) - CPP_PUTS (pfile, "@-", 2); - parse_name (pfile, GETC ()); - return CPP_NAME; - } - else if (is_space [c]) - { - CPP_RESERVE (pfile, 2); - if (pfile->output_escapes) - CPP_PUTC_Q (pfile, '@'); - CPP_PUTC_Q (pfile, c); - return CPP_HSPACE; - } - } - if (pfile->output_escapes) - { - CPP_PUTS (pfile, "@@", 2); - return CPP_OTHER; - } - goto randomchar; - - case '.': - NEWLINE_FIX; - c2 = PEEKC (); - if (isdigit(c2)) - { - CPP_RESERVE(pfile, 2); - CPP_PUTC_Q (pfile, '.'); - c = GETC (); - goto number; - } - /* FIXME - misses the case "..\\\n." */ - if (c2 == '.' && PEEKN(1) == '.') - { - CPP_RESERVE(pfile, 4); - CPP_PUTC_Q (pfile, '.'); - CPP_PUTC_Q (pfile, '.'); - CPP_PUTC_Q (pfile, '.'); - FORWARD (2); - CPP_NUL_TERMINATE_Q (pfile); - pfile->only_seen_white = 0; - return CPP_3DOTS; - } - goto randomchar; - - op2: - token = CPP_OTHER; - pfile->only_seen_white = 0; - op2any: - CPP_RESERVE(pfile, 3); - CPP_PUTC_Q (pfile, c); - CPP_PUTC_Q (pfile, GETC ()); - CPP_NUL_TERMINATE_Q (pfile); - return token; - - case 'L': - NEWLINE_FIX; - c2 = PEEKC (); - if ((c2 == '\'' || c2 == '\"') && !CPP_TRADITIONAL (pfile)) - { - CPP_PUTC (pfile, c); - c = GETC (); - goto string; - } - goto letter; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - number: - c2 = '.'; - for (;;) - { - CPP_RESERVE (pfile, 2); - CPP_PUTC_Q (pfile, c); - NEWLINE_FIX; - c = PEEKC (); - if (c == EOF) - break; - if (!is_idchar[c] && c != '.' - && ((c2 != 'e' && c2 != 'E') || (c != '+' && c != '-'))) - break; - FORWARD(1); - c2= c; - } - CPP_NUL_TERMINATE_Q (pfile); - pfile->only_seen_white = 0; - return CPP_NUMBER; - case 'b': case 'c': case 'd': case 'h': case 'o': - case 'B': case 'C': case 'D': case 'H': case 'O': - if (opts->chill && PEEKC () == '\'') - { - pfile->only_seen_white = 0; - CPP_RESERVE (pfile, 2); - CPP_PUTC_Q (pfile, c); - CPP_PUTC_Q (pfile, '\''); - FORWARD(1); - for (;;) - { - c = GETC(); - if (c == EOF) - goto chill_number_eof; - if (!is_idchar[c]) - { - if (c == '\\' && PEEKC() == '\n') - { - FORWARD(2); - continue; - } - break; - } - CPP_PUTC (pfile, c); - } - if (c == '\'') - { - CPP_RESERVE (pfile, 2); - CPP_PUTC_Q (pfile, c); - CPP_NUL_TERMINATE_Q (pfile); - return CPP_STRING; - } - else - { - FORWARD(-1); - chill_number_eof: - CPP_NUL_TERMINATE (pfile); - return CPP_NUMBER; - } - } - else - goto letter; - case '_': - case 'a': case 'e': case 'f': case 'g': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'p': case 'q': - case 'r': case 's': case 't': case 'u': case 'v': case 'w': - case 'x': case 'y': case 'z': - case 'A': case 'E': case 'F': case 'G': case 'I': case 'J': - case 'K': case 'M': case 'N': case 'P': case 'Q': case 'R': - case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': - case 'Y': case 'Z': - letter: - { - HASHNODE *hp; - unsigned char *ident; - int before_name_written = CPP_WRITTEN (pfile); - int ident_len; - parse_name (pfile, c); - pfile->only_seen_white = 0; - if (pfile->no_macro_expand) - return CPP_NAME; - ident = pfile->token_buffer + before_name_written; - ident_len = CPP_PWRITTEN (pfile) - ident; - hp = cpp_lookup (pfile, ident, ident_len, -1); - if (!hp) - return CPP_NAME; - if (hp->type == T_DISABLED) - { - if (pfile->output_escapes) - { /* Return "@-IDENT", followed by '\0'. */ - int i; - CPP_RESERVE (pfile, 3); - ident = pfile->token_buffer + before_name_written; - CPP_ADJUST_WRITTEN (pfile, 2); - for (i = ident_len; i >= 0; i--) ident[i+2] = ident[i]; - ident[0] = '@'; - ident[1] = '-'; - } - return CPP_NAME; - } - - /* If macro wants an arglist, verify that a '(' follows. - first skip all whitespace, copying it to the output - after the macro name. Then, if there is no '(', - decide this is not a macro call and leave things that way. */ - if (hp->type == T_MACRO && hp->value.defn->nargs >= 0) - { - struct parse_marker macro_mark; - int is_macro_call; - while (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) - { - cpp_buffer *next_buf; - cpp_skip_hspace (pfile); - if (PEEKC () != EOF) - break; - next_buf = CPP_PREV_BUFFER (CPP_BUFFER (pfile)); - (*CPP_BUFFER (pfile)->cleanup) (CPP_BUFFER (pfile), pfile); - CPP_BUFFER (pfile) = next_buf; - } - parse_set_mark (¯o_mark, pfile); - for (;;) - { - cpp_skip_hspace (pfile); - c = PEEKC (); - is_macro_call = c == '('; - if (c != '\n') - break; - FORWARD (1); - } - if (!is_macro_call) - parse_goto_mark (¯o_mark, pfile); - parse_clear_mark (¯o_mark); - if (!is_macro_call) - return CPP_NAME; - } - /* This is now known to be a macro call. */ - - /* it might not actually be a macro. */ - if (hp->type != T_MACRO) { - int xbuf_len; U_CHAR *xbuf; - CPP_SET_WRITTEN (pfile, before_name_written); - special_symbol (hp, pfile); - xbuf_len = CPP_WRITTEN (pfile) - before_name_written; - xbuf = (U_CHAR *) Safe_malloc (xbuf_len + 1); - CPP_SET_WRITTEN (pfile, before_name_written); - bcopy (CPP_PWRITTEN (pfile), xbuf, xbuf_len + 1); - push_macro_expansion (pfile, xbuf, xbuf_len, hp); - } - else - { - /* Expand the macro, reading arguments as needed, - and push the expansion on the input stack. */ - macroexpand (pfile, hp); - CPP_SET_WRITTEN (pfile, before_name_written); - } - - /* An extra "@ " is added to the end of a macro expansion - to prevent accidental token pasting. We prefer to avoid - unneeded extra spaces (for the sake of cpp-using tools like - imake). Here we remove the space if it is safe to do so. */ - if (pfile->buffer->rlimit - pfile->buffer->cur >= 3 - && pfile->buffer->rlimit[-2] == '@' - && pfile->buffer->rlimit[-1] == ' ') - { - int c1 = pfile->buffer->rlimit[-3]; - int c2 = CPP_BUF_PEEK (CPP_PREV_BUFFER (CPP_BUFFER (pfile))); - if (c2 == EOF || ! unsafe_chars (c1, c2)) - pfile->buffer->rlimit -= 2; - } - } - goto get_next; - - case ' ': case '\t': case '\v': case '\r': - for (;;) - { - CPP_PUTC (pfile, c); - c = PEEKC (); - if (c == EOF || !is_hor_space[c]) - break; - FORWARD(1); - } - return CPP_HSPACE; - - case '\\': - c2 = PEEKC (); - if (c2 != '\n') - goto randomchar; - token = CPP_HSPACE; - goto op2any; - - case '\n': - CPP_PUTC (pfile, c); - if (pfile->only_seen_white == 0) - pfile->only_seen_white = 1; - pfile->lineno++; - output_line_command (pfile, 1, same_file); - return CPP_VSPACE; - - case '(': token = CPP_LPAREN; goto char1; - case ')': token = CPP_RPAREN; goto char1; - case '{': token = CPP_LBRACE; goto char1; - case '}': token = CPP_RBRACE; goto char1; - case ',': token = CPP_COMMA; goto char1; - case ';': token = CPP_SEMICOLON; goto char1; - - randomchar: - default: - token = CPP_OTHER; - char1: - pfile->only_seen_white = 0; - CPP_PUTC (pfile, c); - return token; - } - } -} - -/* Like cpp_get_token, but skip spaces and comments. */ -enum cpp_token -cpp_get_non_space_token ( - cpp_reader *pfile) -{ - int old_written = CPP_WRITTEN (pfile); - for (;;) - { - enum cpp_token token = cpp_get_token (pfile); - if (token != CPP_COMMENT && token != CPP_POP - && token != CPP_HSPACE && token != CPP_VSPACE) - return token; - CPP_SET_WRITTEN (pfile, old_written); - } -} - -/* Parse an identifier starting with C. */ - -int -parse_name ( - cpp_reader *pfile, int c) -{ - for (;;) - { - if (! is_idchar[c]) - { - if (c == '\\' && PEEKC() == '\n') - { - FORWARD(2); - continue; - } - FORWARD (-1); - break; - } - - CPP_RESERVE(pfile, 2); /* One more for final NUL. */ - CPP_PUTC_Q (pfile, c); - c = GETC(); - if (c == EOF) - break; - } - CPP_NUL_TERMINATE_Q (pfile); - return 1; -} - - -/* Maintain and search list of included files, for #import. */ - -/* Hash a file name for import_hash_table. */ - -static int -import_hash ( - char *f) -{ - int val = 0; - - while (*f) val += *f++; - return (val%IMPORT_HASH_SIZE); -} - -/* Search for file FILENAME in import_hash_table. - Return -2 if found, either a matching name or a matching inode. - Otherwise, open the file and return a file descriptor if successful - or -1 if unsuccessful. */ - -static int -lookup_import ( - cpp_reader *pfile, - char *filename, - struct file_name_list *searchptr) -{ - struct import_file *i; - int h; - int hashval; - struct stat sb; - int fd; - - hashval = import_hash (filename); - - /* Attempt to find file in list of already included files */ - i = pfile->import_hash_table[hashval]; - - while (i) { - if (!strcmp (filename, i->name)) - return -2; /* return found */ - i = i->next; - } - /* Open it and try a match on inode/dev */ - fd = open_include_file (pfile, filename, searchptr); - if (fd < 0) - return fd; - fstat (fd, &sb); - for (h = 0; h < IMPORT_HASH_SIZE; h++) { - i = pfile->import_hash_table[h]; - while (i) { - /* Compare the inode and the device. - Supposedly on some systems the inode is not a scalar. */ - if (!bcmp ((char *) &i->inode, (char *) &sb.st_ino, sizeof (sb.st_ino)) - && i->dev == sb.st_dev) { - close (fd); - return -2; /* return found */ - } - i = i->next; - } - } - return fd; /* Not found, return open file */ -} - -/* Add the file FNAME, open on descriptor FD, to import_hash_table. */ - -static void -add_import ( - cpp_reader *pfile, - int fd, - char *fname) -{ - struct import_file *i; - int hashval; - struct stat sb; - - hashval = import_hash (fname); - fstat (fd, &sb); - i = (struct import_file *)Safe_malloc (sizeof (struct import_file)); - i->name = (char *)Safe_malloc (strlen (fname)+1); - strcpy (i->name, fname); - bcopy ((char *) &sb.st_ino, (char *) &i->inode, sizeof (sb.st_ino)); - i->dev = sb.st_dev; - i->next = pfile->import_hash_table[hashval]; - pfile->import_hash_table[hashval] = i; -} - -/* The file_name_map structure holds a mapping of file names for a - particular directory. This mapping is read from the file named - FILE_NAME_MAP_FILE in that directory. Such a file can be used to - map filenames on a file system with severe filename restrictions, - such as DOS. The format of the file name map file is just a series - of lines with two tokens on each line. The first token is the name - to map, and the second token is the actual name to use. */ - -struct file_name_map -{ - struct file_name_map *map_next; - char *map_from; - char *map_to; -}; - -#define FILE_NAME_MAP_FILE "header.gcc" - -/* Read a space delimited string of unlimited length from a stdio - file. */ - -static char * -read_filename_string ( - int ch, - FILE *f) -{ - char *alloc, *set; - int len; - - len = 20; - set = alloc = Safe_malloc (len + 1); - if (! is_space[ch]) - { - *set++ = ch; - while ((ch = getc (f)) != EOF && ! is_space[ch]) - { - if (set - alloc == len) - { - len *= 2; - alloc = Safe_realloc(alloc, len + 1); - set = alloc + len / 2; - } - *set++ = ch; - } - } - *set = '\0'; - ungetc (ch, f); - return alloc; -} - -/* This structure holds a linked list of file name maps, one per directory. */ -struct file_name_map_list -{ - struct file_name_map_list *map_list_next; - char *map_list_name; - struct file_name_map *map_list_map; -}; - -/* Read the file name map file for DIRNAME. */ - -static struct file_name_map * -read_name_map ( - cpp_reader *pfile, - char *dirname) -{ - register struct file_name_map_list *map_list_ptr; - char *name; - FILE *f; - - for (map_list_ptr = CPP_OPTIONS (pfile)->map_list; map_list_ptr; - map_list_ptr = map_list_ptr->map_list_next) - if (! strcmp (map_list_ptr->map_list_name, dirname)) - return map_list_ptr->map_list_map; - - map_list_ptr = ((struct file_name_map_list *) - Safe_malloc (sizeof (struct file_name_map_list))); - map_list_ptr->map_list_name = savestring (dirname); - map_list_ptr->map_list_map = NULL; - - name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2); - strcpy (name, dirname); - if (*dirname) - strcat (name, "/"); - strcat (name, FILE_NAME_MAP_FILE); - f = fopen (name, "r"); - if (!f) - map_list_ptr->map_list_map = NULL; - else - { - int ch; - int dirlen = strlen (dirname); - - while ((ch = getc (f)) != EOF) - { - char *from, *to; - struct file_name_map *ptr; - - if (is_space[ch]) - continue; - from = read_filename_string (ch, f); - while ((ch = getc (f)) != EOF && is_hor_space[ch]) - ; - to = read_filename_string (ch, f); - - ptr = ((struct file_name_map *) - Safe_malloc (sizeof (struct file_name_map))); - ptr->map_from = from; - - /* Make the real filename absolute. */ - if (*to == '/') - ptr->map_to = to; - else - { - ptr->map_to = Safe_malloc (dirlen + strlen (to) + 2); - strcpy (ptr->map_to, dirname); - ptr->map_to[dirlen] = '/'; - strcpy (ptr->map_to + dirlen + 1, to); - Safe_free (to); - } - - ptr->map_next = map_list_ptr->map_list_map; - map_list_ptr->map_list_map = ptr; - - while ((ch = getc (f)) != '\n') - if (ch == EOF) - break; - } - fclose (f); - } - - map_list_ptr->map_list_next = CPP_OPTIONS (pfile)->map_list; - CPP_OPTIONS (pfile)->map_list = map_list_ptr; - - return map_list_ptr->map_list_map; -} - -/* Try to open include file FILENAME. SEARCHPTR is the directory - being tried from the include file search path. This function maps - filenames on file systems based on information read by - read_name_map. */ - -static int -open_include_file ( - cpp_reader *pfile, - char *filename, - struct file_name_list *searchptr) -{ - register struct file_name_map *map; - register char *from; - char *p, *dir; - - if (searchptr && ! searchptr->got_name_map) - { - searchptr->name_map = read_name_map (pfile, - searchptr->fname - ? searchptr->fname : "."); - searchptr->got_name_map = 1; - } - - /* First check the mapping for the directory we are using. */ - if (searchptr && searchptr->name_map) - { - from = filename; - if (searchptr->fname) - from += strlen (searchptr->fname) + 1; - for (map = searchptr->name_map; map; map = map->map_next) - { - if (! strcmp (map->map_from, from)) - { - /* Found a match. */ - return open (map->map_to, O_RDONLY, 0666); - } - } - } - - /* Try to find a mapping file for the particular directory we are - looking in. Thus #include will look up sys/types.h - in /usr/include/header.gcc and look up types.h in - /usr/include/sys/header.gcc. */ - p = rindex (filename, '/'); - if (! p) - p = filename; - if (searchptr - && searchptr->fname - && (int) strlen (searchptr->fname) == p - filename - && ! strncmp (searchptr->fname, filename, p - filename)) - { - /* FILENAME is in SEARCHPTR, which we've already checked. */ - return open (filename, O_RDONLY, 0666); - } - - if (p == filename) - { - dir = "."; - from = filename; - } - else - { - dir = (char *) alloca (p - filename + 1); - bcopy (filename, dir, p - filename); - dir[p - filename] = '\0'; - from = p + 1; - } - for (map = read_name_map (pfile, dir); map; map = map->map_next) - if (! strcmp (map->map_from, from)) - return open (map->map_to, O_RDONLY, 0666); - - return open (filename, O_RDONLY, 0666); -} - -/* Process the contents of include file FNAME, already open on descriptor F, - with output to OP. - SYSTEM_HEADER_P is 1 if this file resides in any one of the known - "system" include directories (as decided by the `is_system_include' - function above). - DIRPTR is the link in the dir path through which this file was found, - or 0 if the file name was absolute or via the current directory. - Return 1 on success, 0 on failure. - - The caller is responsible for the cpp_push_buffer. */ - -static int -finclude ( - cpp_reader *pfile, - int f, - char *fname, - int system_header_p, - struct file_name_list *dirptr) -{ - int st_mode; - long st_size; - long i; - int length; - cpp_buffer *fp; /* For input stack frame */ - /* int missing_newline = 0; # KILL */ - - if (file_size_and_mode (f, &st_mode, &st_size) < 0) - { - cpp_perror_with_name (pfile, fname); - close (f); - cpp_pop_buffer (pfile); - return 0; - } - - fp = CPP_BUFFER (pfile); - fp->nominal_fname = fp->fname = fname; -#if 0 - fp->length = 0; -#endif - fp->dir = dirptr; - fp->system_header_p = system_header_p; - fp->lineno = 1; - fp->colno = 1; - fp->cleanup = file_cleanup; - - if (S_ISREG (st_mode)) { - fp->buf = (U_CHAR *) Safe_malloc (st_size + 2); - fp->alimit = fp->buf + st_size + 2; - fp->cur = fp->buf; - - /* Read the file contents, knowing that st_size is an upper bound - on the number of bytes we can read. */ - length = safe_read (f, fp->buf, st_size); - fp->rlimit = fp->buf + length; - if (length < 0) goto nope; - } - else if (S_ISDIR (st_mode)) { - cpp_error (pfile, "directory `%s' specified in #include", fname); - close (f); - return 0; - } else { - /* Cannot count its file size before reading. - First read the entire file into heap and - copy them into buffer on stack. */ - - int bsize = 2000; - - st_size = 0; - fp->buf = (U_CHAR *) Safe_malloc (bsize + 2); - - for (;;) { - i = safe_read (f, fp->buf + st_size, bsize - st_size); - if (i < 0) - goto nope; /* error! */ - st_size += i; - if (st_size != bsize) - break; /* End of file */ - bsize *= 2; - fp->buf = (U_CHAR *) Safe_realloc(fp->buf, bsize + 2); - } - fp->cur = fp->buf; - length = st_size; - } - - if ((length > 0 && fp->buf[length - 1] != '\n') - /* Backslash-newline at end is not good enough. */ - || (length > 1 && fp->buf[length - 2] == '\\')) { - fp->buf[length++] = '\n'; -#if 0 - missing_newline = 1; -#endif - } - fp->buf[length] = '\0'; - fp->rlimit = fp->buf + length; - - /* Close descriptor now, so nesting does not use lots of descriptors. */ - close (f); - - /* Must do this before calling trigraph_pcp, so that the correct file name - will be printed in warning messages. */ - - pfile->input_stack_listing_current = 0; - -#if 0 - if (!no_trigraphs) - trigraph_pcp (fp); -#endif - -#if 0 - rescan (op, 0); - - if (missing_newline) - fp->lineno--; - - if (CPP_PEDANTIC (pfile) && missing_newline) - pedwarn ("file does not end in newline"); - - indepth--; - input_file_stack_tick++; - Safe_free (fp->buf); -#endif - return 1; - - nope: - - cpp_perror_with_name (pfile, fname); - close (f); - Safe_free (fp->buf); - return 1; -} - -int -push_parse_file ( - cpp_reader *pfile, - char *fname) -{ - struct cpp_options *opts = CPP_OPTIONS (pfile); - struct cpp_pending *pend; - char *p; - int f; - cpp_buffer *fp; - - /* The code looks at the defaults through this pointer, rather than through - the constant structure above. This pointer gets changed if an environment - variable specifies other defaults. */ - struct default_include *include_defaults = include_defaults_array; - - /* Add dirs from CPATH after dirs from -I. */ - /* There seems to be confusion about what CPATH should do, - so for the moment it is not documented. */ - /* Some people say that CPATH should replace the standard include dirs, - but that seems pointless: it comes before them, so it overrides them - anyway. */ - p = (char *) getenv ("CPATH"); - if (p != 0 && ! opts->no_standard_includes) - path_include (pfile, p); - - /* Now that dollars_in_ident is known, initialize is_idchar. */ - initialize_char_syntax (opts); - - /* Do partial setup of input buffer for the sake of generating - early #line directives (when -g is in effect). */ - fp = cpp_push_buffer (pfile, NULL, 0); - if (opts->in_fname == NULL) - opts->in_fname = ""; - fp->nominal_fname = fp->fname = opts->in_fname; - fp->lineno = 0; - - /* Install __LINE__, etc. Must follow initialize_char_syntax - and option processing. */ - initialize_builtins (pfile); - - /* Do standard #defines and assertions - that identify system and machine type. */ - - if (!opts->inhibit_predefs) { - char *p = (char *) alloca (strlen (predefs) + 1); - strcpy (p, predefs); - while (*p) { - char *q; - while (*p == ' ' || *p == '\t') - p++; - /* Handle -D options. */ - if (p[0] == '-' && p[1] == 'D') { - q = &p[2]; - while (*p && *p != ' ' && *p != '\t') - p++; - if (*p != 0) - *p++= 0; - if (opts->debug_output) - output_line_command (pfile, 0, same_file); - cpp_define (pfile, q); - while (*p == ' ' || *p == '\t') - p++; - } else if (p[0] == '-' && p[1] == 'A') { - /* Handle -A options (assertions). */ - char *assertion; - char *past_name; - char *value; - char *past_value; - char *termination; - int save_char; - - assertion = &p[2]; - past_name = assertion; - /* Locate end of name. */ - while (*past_name && *past_name != ' ' - && *past_name != '\t' && *past_name != '(') - past_name++; - /* Locate `(' at start of value. */ - value = past_name; - while (*value && (*value == ' ' || *value == '\t')) - value++; - if (*value++ != '(') - abort (); - while (*value && (*value == ' ' || *value == '\t')) - value++; - past_value = value; - /* Locate end of value. */ - while (*past_value && *past_value != ' ' - && *past_value != '\t' && *past_value != ')') - past_value++; - termination = past_value; - while (*termination && (*termination == ' ' || *termination == '\t')) - termination++; - if (*termination++ != ')') - abort (); - if (*termination && *termination != ' ' && *termination != '\t') - abort (); - /* Temporarily null-terminate the value. */ - save_char = *termination; - *termination = '\0'; - /* Install the assertion. */ - make_assertion (pfile, "-A", assertion); - *termination = (char) save_char; - p = termination; - while (*p == ' ' || *p == '\t') - p++; - } else { - abort (); - } - } - } - - /* Now handle the command line options. */ - - /* Do -U's, -D's and -A's in the order they were seen. */ - /* First reverse the list. */ - opts->pending = nreverse_pending (opts->pending); - - for (pend = opts->pending; pend; pend = pend->next) - { - if (pend->cmd != NULL && pend->cmd[0] == '-') - { - switch (pend->cmd[1]) - { - case 'U': - if (opts->debug_output) - output_line_command (pfile, 0, same_file); - do_undef (pfile, NULL, pend->arg, pend->arg + strlen (pend->arg)); - break; - case 'D': - if (opts->debug_output) - output_line_command (pfile, 0, same_file); - cpp_define (pfile, pend->arg); - break; - case 'A': - make_assertion (pfile, "-A", pend->arg); - break; - } - } - } - - opts->done_initializing = 1; - - { /* read the appropriate environment variable and if it exists - replace include_defaults with the listed path. */ - char *epath = 0; - switch ((opts->objc << 1) + opts->cplusplus) - { - case 0: - epath = getenv ("C_INCLUDE_PATH"); - break; - case 1: - epath = getenv ("CPLUS_INCLUDE_PATH"); - break; - case 2: - epath = getenv ("OBJC_INCLUDE_PATH"); - break; - case 3: - epath = getenv ("OBJCPLUS_INCLUDE_PATH"); - break; - } - /* If the environment var for this language is set, - add to the default list of include directories. */ - if (epath) { - char *nstore = (char *) alloca (strlen (epath) + 2); - int num_dirs; - char *startp, *endp; - - for (num_dirs = 1, startp = epath; *startp; startp++) - if (*startp == PATH_SEPARATOR) - num_dirs++; - include_defaults - = (struct default_include *) Safe_malloc ((num_dirs - * sizeof (struct default_include)) - + sizeof (include_defaults_array)); - startp = endp = epath; - num_dirs = 0; - while (1) { - /* Handle cases like c:/usr/lib:d:/gcc/lib */ - if ((*endp == PATH_SEPARATOR) - || *endp == 0) { - strncpy (nstore, startp, endp-startp); - if (endp == startp) - strcpy (nstore, "."); - else - nstore[endp-startp] = '\0'; - - include_defaults[num_dirs].fname = savestring (nstore); - include_defaults[num_dirs].cplusplus = opts->cplusplus; - include_defaults[num_dirs].cxx_aware = 1; - num_dirs++; - if (*endp == '\0') - break; - endp = startp = endp + 1; - } else - endp++; - } - /* Put the usual defaults back in at the end. */ - bcopy ((char *) include_defaults_array, - (char *) &include_defaults[num_dirs], - sizeof (include_defaults_array)); - } - } - - append_include_chain (pfile, opts->before_system, opts->last_before_system); - opts->first_system_include = opts->before_system; - - /* Unless -fnostdinc, - tack on the standard include file dirs to the specified list */ - if (!opts->no_standard_includes) { - struct default_include *p = include_defaults; - char *specd_prefix = opts->include_prefix; - char *default_prefix = savestring (GCC_INCLUDE_DIR); - int default_len = 0; - /* Remove the `include' from /usr/local/lib/gcc.../include. */ - if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) { - default_len = strlen (default_prefix) - 7; - default_prefix[default_len] = 0; - } - /* Search "translated" versions of GNU directories. - These have /usr/local/lib/gcc... replaced by specd_prefix. */ - if (specd_prefix != 0 && default_len != 0) - for (p = include_defaults; p->fname; p++) { - /* Some standard dirs are only for C++. */ - if (!p->cplusplus - || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) { - /* Does this dir start with the prefix? */ - if (!strncmp (p->fname, default_prefix, default_len)) { - /* Yes; change prefix and add to search list. */ - struct file_name_list *new - = (struct file_name_list *) Safe_malloc (sizeof (struct file_name_list)); - int this_len = strlen (specd_prefix) + strlen (p->fname) - default_len; - char *str = (char *) Safe_malloc (this_len + 1); - strcpy (str, specd_prefix); - strcat (str, p->fname + default_len); - new->fname = str; - new->control_macro = 0; - new->c_system_include_path = !p->cxx_aware; - new->got_name_map = 0; - append_include_chain (pfile, new, new); - if (opts->first_system_include == 0) - opts->first_system_include = new; - } - } - } - /* Search ordinary names for GNU include directories. */ - for (p = include_defaults; p->fname; p++) { - /* Some standard dirs are only for C++. */ - if (!p->cplusplus - || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) { - struct file_name_list *new - = (struct file_name_list *) Safe_malloc (sizeof (struct file_name_list)); - new->control_macro = 0; - new->c_system_include_path = !p->cxx_aware; - new->fname = p->fname; - new->got_name_map = 0; - append_include_chain (pfile, new, new); - if (opts->first_system_include == 0) - opts->first_system_include = new; - } - } - } - - /* Tack the after_include chain at the end of the include chain. */ - append_include_chain (pfile, opts->after_include, opts->last_after_include); - if (opts->first_system_include == 0) - opts->first_system_include = opts->after_include; - - /* With -v, print the list of dirs to search. */ - if (opts->verbose) { - struct file_name_list *p; - fprintf (stderr, "#include \"...\" search starts here:\n"); - for (p = opts->include; p; p = p->next) { - if (p == opts->first_bracket_include) - fprintf (stderr, "#include <...> search starts here:\n"); - fprintf (stderr, " %s\n", p->fname); - } - fprintf (stderr, "End of search list.\n"); - } - - /* Scan the -imacros files before the main input. - Much like #including them, but with no_output set - so that only their macro definitions matter. */ - - opts->no_output++; pfile->no_record_file++; - for (pend = opts->pending; pend; pend = pend->next) - { - if (pend->cmd != NULL && strcmp (pend->cmd, "-imacros") == 0) - { - int fd = open (pend->arg, O_RDONLY, 0666); - if (fd < 0) - { - cpp_perror_with_name (pfile, pend->arg); - return FATAL_EXIT_CODE; - } - cpp_push_buffer (pfile, NULL, 0); - finclude (pfile, fd, pend->arg, 0, NULL_PTR); - cpp_scan_buffer (pfile); - } - } - opts->no_output--; pfile->no_record_file--; - - /* Copy the entire contents of the main input file into - the stacked input buffer previously allocated for it. */ - if (fname == NULL || *fname == 0) { - fname = ""; - f = 0; - } else if ((f = open (fname, O_RDONLY, 0666)) < 0) - cpp_pfatal_with_name (pfile, fname); - - /* -MG doesn't select the form of output and must be specified with one of - -M or -MM. -MG doesn't make sense with -MD or -MMD since they don't - inhibit compilation. */ - if (opts->print_deps_missing_files - && (opts->print_deps == 0 || !opts->no_output)) - fatal (pfile, "-MG must be specified with one of -M or -MM"); - - /* Either of two environment variables can specify output of deps. - Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET", - where OUTPUT_FILE is the file to write deps info to - and DEPS_TARGET is the target to mention in the deps. */ - - if (opts->print_deps == 0 - && (getenv ("SUNPRO_DEPENDENCIES") != 0 - || getenv ("DEPENDENCIES_OUTPUT") != 0)) { - char *spec = getenv ("DEPENDENCIES_OUTPUT"); - char *s; - char *output_file; - - if (spec == 0) - { - spec = getenv ("SUNPRO_DEPENDENCIES"); - opts->print_deps = 2; - } - else - opts->print_deps = 1; - - s = spec; - /* Find the space before the DEPS_TARGET, if there is one. */ - /* This should use index. (mrs) */ - while (*s != 0 && *s != ' ') s++; - if (*s != 0) - { - opts->deps_target = s + 1; - output_file = (char *) Safe_malloc (s - spec + 1); - bcopy (spec, output_file, s - spec); - output_file[s - spec] = 0; - } - else - { - opts->deps_target = 0; - output_file = spec; - } - - opts->deps_file = output_file; - opts->print_deps_append = 1; - } - - /* For -M, print the expected object file name - as the target of this Make-rule. */ - if (opts->print_deps) - { - pfile->deps_allocated_size = 200; - pfile->deps_buffer = (char *) Safe_malloc (pfile->deps_allocated_size); - pfile->deps_buffer[0] = 0; - pfile->deps_size = 0; - pfile->deps_column = 0; - - if (opts->deps_target) - deps_output (pfile, opts->deps_target, ':'); - else if (*opts->in_fname == 0) - deps_output (pfile, "-", ':'); - else - { - char *p, *q; - int len; - - /* Discard all directory prefixes from filename. */ - if ((q = rindex (opts->in_fname, '/')) != NULL -#ifdef DIR_SEPARATOR - && (q = rindex (opts->in_fname, DIR_SEPARATOR)) != NULL -#endif - ) - ++q; - else - q = opts->in_fname; - - /* Copy remainder to mungable area. */ - p = (char *) alloca (strlen(q) + 8); - strcpy (p, q); - - /* Output P, but remove known suffixes. */ - len = strlen (p); - q = p + len; - if (len >= 2 - && p[len - 2] == '.' - && index("cCsSm", p[len - 1])) - q = p + (len - 2); - else if (len >= 3 - && p[len - 3] == '.' - && p[len - 2] == 'c' - && p[len - 1] == 'c') - q = p + (len - 3); - else if (len >= 4 - && p[len - 4] == '.' - && p[len - 3] == 'c' - && p[len - 2] == 'x' - && p[len - 1] == 'x') - q = p + (len - 4); - else if (len >= 4 - && p[len - 4] == '.' - && p[len - 3] == 'c' - && p[len - 2] == 'p' - && p[len - 1] == 'p') - q = p + (len - 4); - - /* Supply our own suffix. */ -#ifndef VMS -#ifdef _FORASXXXX_ - strcpy (q,".rel"); -#else - strcpy (q, ".o"); -#endif -#else - strcpy (q, ".obj"); -#endif - - deps_output (pfile, p, ':'); - deps_output (pfile, opts->in_fname, ' '); - } - } - -#if 0 - /* Make sure data ends with a newline. And put a null after it. */ - - if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n') - /* Backslash-newline at end is not good enough. */ - || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) { - fp->buf[fp->length++] = '\n'; - missing_newline = 1; - } - fp->buf[fp->length] = '\0'; - - /* Unless inhibited, convert trigraphs in the input. */ - - if (!no_trigraphs) - trigraph_pcp (fp); -#endif - - /* Scan the -include files before the main input. - We push these in reverse order, so that the first one is handled first. */ - - pfile->no_record_file++; - opts->pending = nreverse_pending (opts->pending); - for (pend = opts->pending; pend; pend = pend->next) - { - if (pend->cmd != NULL && strcmp (pend->cmd, "-include") == 0) - { - int fd = open (pend->arg, O_RDONLY, 0666); - if (fd < 0) - { - cpp_perror_with_name (pfile, pend->arg); - return FATAL_EXIT_CODE; - } - cpp_push_buffer (pfile, NULL, 0); - finclude (pfile, fd, pend->arg, 0, NULL_PTR); - } - } - pfile->no_record_file--; - - /* Free the pending list. */ - for (pend = opts->pending; pend; ) - { - struct cpp_pending *next = pend->next; - Safe_free (pend); - pend = next; - } - opts->pending = NULL; - -#if 0 - /* Scan the input, processing macros and directives. */ - - rescan (&outbuf, 0); - - if (missing_newline) - fp->lineno--; - - if (CPP_PEDANTIC (pfile) && missing_newline) - pedwarn ("file does not end in newline"); - -#endif - if (finclude (pfile, f, fname, 0, NULL_PTR)) - output_line_command (pfile, 0, same_file); - return SUCCESS_EXIT_CODE; -} - -void -init_parse_file ( - cpp_reader *pfile) -{ - bzero ((char *) pfile, sizeof (cpp_reader)); - pfile->get_token = cpp_get_token; - - pfile->token_buffer_size = 200; - pfile->token_buffer = (U_CHAR*)Safe_malloc (pfile->token_buffer_size); - CPP_SET_WRITTEN (pfile, 0); - - pfile->system_include_depth = 0; - pfile->dont_repeat_files = 0; - pfile->all_include_files = 0; - pfile->max_include_len = 0; - pfile->timebuf = NULL; - pfile->only_seen_white = 1; - pfile->buffer = CPP_NULL_BUFFER(pfile); -} - -static struct cpp_pending * -nreverse_pending ( - struct cpp_pending *list) - -{ - register struct cpp_pending *prev = 0, *next, *pend; - for (pend = list; pend; pend = next) - { - next = pend->next; - pend->next = prev; - prev = pend; - } - return prev; -} - -static void -push_pending ( - cpp_reader *pfile, - char *cmd, - char *arg) -{ - struct cpp_pending *pend - = (struct cpp_pending*)Safe_malloc (sizeof (struct cpp_pending)); - pend->cmd = cmd; - pend->arg = arg; - pend->next = CPP_OPTIONS (pfile)->pending; - CPP_OPTIONS (pfile)->pending = pend; -} - -/* Handle command-line options in (argc, argv). - Can be called multiple times, to handle multiple sets of options. - Returns if an unrecognized option is seen. - Returns number of handled arguments. */ - -int -cpp_handle_options ( - cpp_reader *pfile, - int argc, - char **argv) -{ - int i; - struct cpp_options *opts = CPP_OPTIONS (pfile); - for (i = 0; i < argc; i++) { - if (argv[i][0] != '-') { - if (opts->out_fname != NULL) - fatal ("Usage: %s [switches] input output", argv[0]); - else if (opts->in_fname != NULL) - opts->out_fname = argv[i]; - else - opts->in_fname = argv[i]; - } else { - switch (argv[i][1]) { - - case 'i': - if (!strcmp (argv[i], "-include") - || !strcmp (argv[i], "-imacros")) { - if (i + 1 == argc) - fatal ("Filename missing after `%s' option", argv[i]); - else - push_pending (pfile, argv[i], argv[i+1]), i++; - } - if (!strcmp (argv[i], "-iprefix")) { - if (i + 1 == argc) - fatal ("Filename missing after `-iprefix' option"); - else - opts->include_prefix = argv[++i]; - } - if (!strcmp (argv[i], "-ifoutput")) { - opts->output_conditionals = 1; - } - if (!strcmp (argv[i], "-isystem")) { - struct file_name_list *dirtmp; - - if (i + 1 == argc) - fatal ("Filename missing after `-isystem' option"); - - dirtmp = (struct file_name_list *) - Safe_malloc (sizeof (struct file_name_list)); - dirtmp->next = 0; - dirtmp->control_macro = 0; - dirtmp->c_system_include_path = 1; - dirtmp->fname = (char *) Safe_malloc (strlen (argv[i+1]) + 1); - strcpy (dirtmp->fname, argv[++i]); - dirtmp->got_name_map = 0; - - if (opts->before_system == 0) - opts->before_system = dirtmp; - else - opts->last_before_system->next = dirtmp; - opts->last_before_system = dirtmp; /* Tail follows the last one */ - } - /* Add directory to end of path for includes, - with the default prefix at the front of its name. */ - if (!strcmp (argv[i], "-iwithprefix")) { - struct file_name_list *dirtmp; - char *prefix; - - if (opts->include_prefix != 0) - prefix = opts->include_prefix; - else { - prefix = savestring (GCC_INCLUDE_DIR); - /* Remove the `include' from /usr/local/lib/gcc.../include. */ - if (!strcmp (prefix + strlen (prefix) - 8, "/include")) - prefix[strlen (prefix) - 7] = 0; - } - - dirtmp = (struct file_name_list *) - Safe_malloc (sizeof (struct file_name_list)); - dirtmp->next = 0; /* New one goes on the end */ - dirtmp->control_macro = 0; - dirtmp->c_system_include_path = 0; - if (i + 1 == argc) - fatal ("Directory name missing after `-iwithprefix' option"); - - dirtmp->fname = (char *) Safe_malloc (strlen (argv[i+1]) - + strlen (prefix) + 1); - strcpy (dirtmp->fname, prefix); - strcat (dirtmp->fname, argv[++i]); - dirtmp->got_name_map = 0; - - if (opts->after_include == 0) - opts->after_include = dirtmp; - else - opts->last_after_include->next = dirtmp; - opts->last_after_include = dirtmp; /* Tail follows the last one */ - } - /* Add directory to main path for includes, - with the default prefix at the front of its name. */ - if (!strcmp (argv[i], "-iwithprefixbefore")) { - struct file_name_list *dirtmp; - char *prefix; - - if (opts->include_prefix != 0) - prefix = opts->include_prefix; - else { - prefix = savestring (GCC_INCLUDE_DIR); - /* Remove the `include' from /usr/local/lib/gcc.../include. */ - if (!strcmp (prefix + strlen (prefix) - 8, "/include")) - prefix[strlen (prefix) - 7] = 0; - } - - dirtmp = (struct file_name_list *) - Safe_malloc (sizeof (struct file_name_list)); - dirtmp->next = 0; /* New one goes on the end */ - dirtmp->control_macro = 0; - dirtmp->c_system_include_path = 0; - if (i + 1 == argc) - fatal ("Directory name missing after `-iwithprefixbefore' option"); - - dirtmp->fname = (char *) Safe_malloc (strlen (argv[i+1]) - + strlen (prefix) + 1); - strcpy (dirtmp->fname, prefix); - strcat (dirtmp->fname, argv[++i]); - dirtmp->got_name_map = 0; - - append_include_chain (pfile, dirtmp, dirtmp); - } - /* Add directory to end of path for includes. */ - if (!strcmp (argv[i], "-idirafter")) { - struct file_name_list *dirtmp; - - dirtmp = (struct file_name_list *) - Safe_malloc (sizeof (struct file_name_list)); - dirtmp->next = 0; /* New one goes on the end */ - dirtmp->control_macro = 0; - dirtmp->c_system_include_path = 0; - if (i + 1 == argc) - fatal ("Directory name missing after `-idirafter' option"); - else - dirtmp->fname = argv[++i]; - dirtmp->got_name_map = 0; - - if (opts->after_include == 0) - opts->after_include = dirtmp; - else - opts->last_after_include->next = dirtmp; - opts->last_after_include = dirtmp; /* Tail follows the last one */ - } - break; - - case 'o': - if (opts->out_fname != NULL) - fatal ("Output filename specified twice"); - if (i + 1 == argc) - fatal ("Filename missing after -o option"); - opts->out_fname = argv[++i]; - if (!strcmp (opts->out_fname, "-")) - opts->out_fname = ""; - break; - - case 'p': - if (!strcmp (argv[i], "-pedantic")) - CPP_PEDANTIC (pfile) = 1; - else if (!strcmp (argv[i], "-pedantic-errors")) { - CPP_PEDANTIC (pfile) = 1; - opts->pedantic_errors = 1; - } -#if 0 - else if (!strcmp (argv[i], "-pcp")) { - char *pcp_fname = argv[++i]; - pcp_outfile = - ((pcp_fname[0] != '-' || pcp_fname[1] != '\0') - ? fopen (pcp_fname, "w") - : fdopen (dup (fileno (stdout)), "w")); - if (pcp_outfile == 0) - cpp_pfatal_with_name (pfile, pcp_fname); - no_precomp = 1; - } -#endif - break; - - case 't': - if (!strcmp (argv[i], "-traditional")) { - opts->traditional = 1; - if (opts->dollars_in_ident > 0) - opts->dollars_in_ident = 1; - } else if (!strcmp (argv[i], "-trigraphs")) { - if (!opts->chill) - opts->no_trigraphs = 0; - } - break; - - case 'l': - if (! strcmp (argv[i], "-lang-c")) - opts->cplusplus = 0, opts->cplusplus_comments = 0, opts->objc = 0; - if (! strcmp (argv[i], "-lang-c++")) - opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->objc = 0; - if (! strcmp (argv[i], "-lang-c-c++-comments")) - opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->objc = 0; - if (! strcmp (argv[i], "-lang-objc")) - opts->objc = 1, opts->cplusplus = 0, opts->cplusplus_comments = 1; - if (! strcmp (argv[i], "-lang-objc++")) - opts->objc = 1, opts->cplusplus = 1, opts->cplusplus_comments = 1; - if (! strcmp (argv[i], "-lang-asm")) - opts->lang_asm = 1; - if (! strcmp (argv[i], "-lint")) - opts->for_lint = 1; - if (! strcmp (argv[i], "-lang-chill")) - opts->objc = 0, opts->cplusplus = 0, opts->chill = 1, - opts->traditional = 1, opts->no_trigraphs = 1; - break; - - case '+': - opts->cplusplus = 1, opts->cplusplus_comments = 1; - break; - - case 'w': - opts->inhibit_warnings = 1; - break; - - case 'W': - if (!strcmp (argv[i], "-Wtrigraphs")) - opts->warn_trigraphs = 1; - else if (!strcmp (argv[i], "-Wno-trigraphs")) - opts->warn_trigraphs = 0; - else if (!strcmp (argv[i], "-Wcomment")) - opts->warn_comments = 1; - else if (!strcmp (argv[i], "-Wno-comment")) - opts->warn_comments = 0; - else if (!strcmp (argv[i], "-Wcomments")) - opts->warn_comments = 1; - else if (!strcmp (argv[i], "-Wno-comments")) - opts->warn_comments = 0; - else if (!strcmp (argv[i], "-Wtraditional")) - opts->warn_stringify = 1; - else if (!strcmp (argv[i], "-Wno-traditional")) - opts->warn_stringify = 0; - else if (!strcmp (argv[i], "-Wimport")) - opts->warn_import = 1; - else if (!strcmp (argv[i], "-Wno-import")) - opts->warn_import = 0; - else if (!strcmp (argv[i], "-Werror")) - opts->warnings_are_errors = 1; - else if (!strcmp (argv[i], "-Wno-error")) - opts->warnings_are_errors = 0; - else if (!strcmp (argv[i], "-Wall")) - { - opts->warn_trigraphs = 1; - opts->warn_comments = 1; - } - break; - - case 'M': - /* The style of the choices here is a bit mixed. - The chosen scheme is a hybrid of keeping all options in one string - and specifying each option in a separate argument: - -M|-MM|-MD file|-MMD file [-MG]. An alternative is: - -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely: - -M[M][G][D file]. This is awkward to handle in specs, and is not - as extensible. */ - /* ??? -MG must be specified in addition to one of -M or -MM. - This can be relaxed in the future without breaking anything. - The converse isn't true. */ - - /* -MG isn't valid with -MD or -MMD. This is checked for later. */ - if (!strcmp (argv[i], "-MG")) - { - opts->print_deps_missing_files = 1; - break; - } - if (!strcmp (argv[i], "-M")) - opts->print_deps = 2; - else if (!strcmp (argv[i], "-MM")) - opts->print_deps = 1; - else if (!strcmp (argv[i], "-MD")) - opts->print_deps = 2; - else if (!strcmp (argv[i], "-MMD")) - opts->print_deps = 1; - /* For -MD and -MMD options, write deps on file named by next arg. */ - if (!strcmp (argv[i], "-MD") || !strcmp (argv[i], "-MMD")) - { - if (i+1 == argc) - fatal ("Filename missing after %s option", argv[i]); - opts->deps_file = argv[++i]; - } - else - { - /* For -M and -MM, write deps on standard output - and suppress the usual output. */ - opts->no_output = 1; - } - break; - - case 'd': - { - char *p = argv[i] + 2; - char c; - while ((c = *p++) != 0) { - /* Arg to -d specifies what parts of macros to dump */ - switch (c) { - case 'M': - opts->dump_macros = dump_only; - opts->no_output = 1; - break; - case 'N': - opts->dump_macros = dump_names; - break; - case 'D': - opts->dump_macros = dump_definitions; - break; - } - } - } - break; - - case 'g': - if (argv[i][2] == '3') - opts->debug_output = 1; - break; - - case 'v': - fprintf (stderr, "GNU CPP version %s", version_string); -#ifdef TARGET_VERSION - TARGET_VERSION; -#endif - fprintf (stderr, "\n"); - // opts->verbose = 1; - break; - - case 'H': - opts->print_include_names = 1; - break; - - case 'D': - if (argv[i][2] != 0) - push_pending (pfile, "-D", argv[i] + 2); - else if (i + 1 == argc) - fatal ("Macro name missing after -D option"); - else - i++, push_pending (pfile, "-D", argv[i]); - break; - - case 'A': - { - char *p; - - if (argv[i][2] != 0) - { - p = argv[i] + 2; - } - else - { - if (++i == argc) - { - fatal ("Assertion missing after -A option"); - } - p = argv[i]; - } - - if (!strcmp (p, "-")) { - struct cpp_pending **ptr; - /* -A- eliminates all predefined macros and assertions. - Let's include also any that were specified earlier - on the command line. That way we can get rid of any - that were passed automatically in from GCC. */ - /* int j; */ - opts->inhibit_predefs = 1; - for (ptr = &opts->pending; *ptr != NULL; ) - { - struct cpp_pending *pend = *ptr; - if (pend->cmd && pend->cmd[0] == '-' - && (pend->cmd[1] == 'D' || pend->cmd[1] == 'A')) - { - *ptr = pend->next; - Safe_free (pend); - } - else - ptr = &pend->next; - } - } else { - push_pending (pfile, "-A", p); - } - } - break; - - case 'U': /* JF #undef something */ - if (argv[i][2] != 0) - push_pending (pfile, "-U", argv[i] + 2); - else if (i + 1 == argc) - fatal ("Macro name missing after -U option"); - else - push_pending (pfile, "-U", argv[i+1]), i++; - break; - - case 'C': - opts->put_out_comments = 1; - break; - - case 'E': /* -E comes from cc -E; ignore it. */ - break; - - case 'P': - opts->no_line_commands = 1; - break; - - case '$': /* Don't include $ in identifiers. */ - opts->dollars_in_ident = 0; - break; - - case 'I': /* Add directory to path for includes. */ - { - struct file_name_list *dirtmp; - - if (! CPP_OPTIONS(pfile)->ignore_srcdir - && !strcmp (argv[i] + 2, "-")) { - CPP_OPTIONS (pfile)->ignore_srcdir = 1; - /* Don't use any preceding -I directories for #include <...>. */ - CPP_OPTIONS (pfile)->first_bracket_include = 0; - } - else { - dirtmp = (struct file_name_list *) - Safe_malloc (sizeof (struct file_name_list)); - dirtmp->next = 0; /* New one goes on the end */ - dirtmp->control_macro = 0; - dirtmp->c_system_include_path = 0; - if (argv[i][2] != 0) - dirtmp->fname = argv[i] + 2; - else if (i + 1 == argc) - fatal ("Directory name missing after -I option"); - else - dirtmp->fname = argv[++i]; - dirtmp->got_name_map = 0; - append_include_chain (pfile, dirtmp, dirtmp); - } - } - break; - - case 'n': - if (!strcmp (argv[i], "-nostdinc")) - /* -nostdinc causes no default include directories. - You must specify all include-file directories with -I. */ - opts->no_standard_includes = 1; - else if (!strcmp (argv[i], "-nostdinc++")) - /* -nostdinc++ causes no default C++-specific include directories. */ - opts->no_standard_cplusplus_includes = 1; -#if 0 - else if (!strcmp (argv[i], "-noprecomp")) - no_precomp = 1; -#endif - break; - - case 'u': - /* Sun compiler passes undocumented switch "-undef". - Let's assume it means to inhibit the predefined symbols. */ - opts->inhibit_predefs = 1; - break; - - case '\0': /* JF handle '-' as file name meaning stdin or stdout */ - if (opts->in_fname == NULL) { - opts->in_fname = ""; - break; - } else if (opts->out_fname == NULL) { - opts->out_fname = ""; - break; - } /* else fall through into error */ - - default: - return i; - } - } - } - return i; -} - -void -cpp_finish ( - cpp_reader *pfile) -{ - struct cpp_options *opts = CPP_OPTIONS (pfile); - - if (opts->print_deps) - { - /* Stream on which to print the dependency information. */ - FILE *deps_stream; - - /* Don't actually write the deps file if compilation has failed. */ - if (pfile->errors == 0) - { - char *deps_mode = opts->print_deps_append ? "a" : "w"; - if (opts->deps_file == 0) - deps_stream = stdout; - else if ((deps_stream = fopen (opts->deps_file, deps_mode)) == 0) - cpp_pfatal_with_name (pfile, opts->deps_file); - fputs (pfile->deps_buffer, deps_stream); - putc ('\n', deps_stream); - if (opts->deps_file) - { - if (ferror (deps_stream) || fclose (deps_stream) != 0) - fatal ("I/O error on output"); - } - } - } -} - -/* Free resources used by PFILE. */ - -void -cpp_cleanup ( - cpp_reader *pfile) -{ - int i; - while ( CPP_BUFFER (pfile) != CPP_NULL_BUFFER (pfile)) - cpp_pop_buffer (pfile); - - if (pfile->token_buffer) - { - Safe_free (pfile->token_buffer); - pfile->token_buffer = NULL; - } - - if (pfile->deps_buffer) - { - Safe_free (pfile->deps_buffer); - pfile->deps_buffer = NULL; - pfile->deps_allocated_size = 0; - } - - while (pfile->if_stack) - { - IF_STACK_FRAME *temp = pfile->if_stack; - pfile->if_stack = temp->next; - Safe_free (temp); - } - - while (pfile->dont_repeat_files) - { - struct file_name_list *temp = pfile->dont_repeat_files; - pfile->dont_repeat_files = temp->next; - Safe_free (temp->fname); - Safe_free (temp); - } - - while (pfile->all_include_files) - { - struct file_name_list *temp = pfile->all_include_files; - pfile->all_include_files = temp->next; - Safe_free (temp->fname); - Safe_free (temp); - } - - for (i = IMPORT_HASH_SIZE; --i >= 0; ) - { - register struct import_file *imp = pfile->import_hash_table[i]; - while (imp) - { - struct import_file *next = imp->next; - Safe_free (imp->name); - Safe_free (imp); - imp = next; - } - pfile->import_hash_table[i] = 0; - } - - for (i = ASSERTION_HASHSIZE; --i >= 0; ) - { - while (pfile->assertion_hashtab[i]) - delete_assertion (pfile->assertion_hashtab[i]); - } - - cpp_hash_cleanup (pfile); -} - -static int -do_assert ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *buf, U_CHAR *limit) -{ - long symstart; /* remember where symbol name starts */ - int c; - int sym_length; /* and how long it is */ - struct arglist *tokens = NULL; - - if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing - && !CPP_BUFFER (pfile)->system_header_p) - cpp_pedwarn (pfile, "ANSI C does not allow `#assert'"); - - cpp_skip_hspace (pfile); - symstart = CPP_WRITTEN (pfile); /* remember where it starts */ - parse_name (pfile, GETC()); - sym_length = check_macro_name (pfile, pfile->token_buffer + symstart, - "assertion"); - - cpp_skip_hspace (pfile); - if (PEEKC() != '(') { - cpp_error (pfile, "missing token-sequence in `#assert'"); - goto error; - } - - { - int error_flag = 0; - tokens = read_token_list (pfile, &error_flag); - if (error_flag) - goto error; - if (tokens == 0) { - cpp_error (pfile, "empty token-sequence in `#assert'"); - goto error; - } - cpp_skip_hspace (pfile); - c = PEEKC (); - if (c != EOF && c != '\n') - cpp_pedwarn (pfile, "junk at end of `#assert'"); - skip_rest_of_line (pfile); - } - - /* If this name isn't already an assertion name, make it one. - Error if it was already in use in some other way. */ - - { - ASSERTION_HASHNODE *hp; - U_CHAR *symname = pfile->token_buffer + symstart; - int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE); - struct tokenlist_list *value - = (struct tokenlist_list *) Safe_malloc (sizeof (struct tokenlist_list)); - - hp = assertion_lookup (pfile, symname, sym_length, hashcode); - if (hp == NULL) { - if (sym_length == 7 && ! strncmp (symname, "defined", sym_length)) - cpp_error (pfile, "`defined' redefined as assertion"); - hp = assertion_install (pfile, symname, sym_length, hashcode); - } - - /* Add the spec'd token-sequence to the list of such. */ - value->tokens = tokens; - value->next = hp->value; - hp->value = value; - } - CPP_SET_WRITTEN (pfile, symstart); /* Pop */ - return 0; - error: - CPP_SET_WRITTEN (pfile, symstart); /* Pop */ - skip_rest_of_line (pfile); - return 1; -} - -static int -do_unassert ( - cpp_reader *pfile, - struct directive *keyword, - U_CHAR *buf, U_CHAR *limit) -{ - long symstart; /* remember where symbol name starts */ - int sym_length; /* and how long it is */ - int c; - - struct arglist *tokens = NULL; - int tokens_specified = 0; - - if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing - && !CPP_BUFFER (pfile)->system_header_p) - cpp_pedwarn (pfile, "ANSI C does not allow `#unassert'"); - - cpp_skip_hspace (pfile); - - symstart = CPP_WRITTEN (pfile); /* remember where it starts */ - parse_name (pfile, GETC()); - sym_length = check_macro_name (pfile, pfile->token_buffer + symstart, - "assertion"); - - cpp_skip_hspace (pfile); - if (PEEKC() == '(') { - int error_flag = 0; - - tokens = read_token_list (pfile, &error_flag); - if (error_flag) - goto error; - if (tokens == 0) { - cpp_error (pfile, "empty token list in `#unassert'"); - goto error; - } - - tokens_specified = 1; - } - - cpp_skip_hspace (pfile); - c = PEEKC (); - if (c != EOF && c != '\n') - cpp_error (pfile, "junk at end of `#unassert'"); - skip_rest_of_line (pfile); - - { - ASSERTION_HASHNODE *hp; - U_CHAR *symname = pfile->token_buffer + symstart; - int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE); - struct tokenlist_list *tail, *prev; - - hp = assertion_lookup (pfile, symname, sym_length, hashcode); - if (hp == NULL) - return 1; - - /* If no token list was specified, then eliminate this assertion - entirely. */ - if (! tokens_specified) - delete_assertion (hp); - else { - /* If a list of tokens was given, then delete any matching list. */ - - tail = hp->value; - prev = 0; - while (tail) { - struct tokenlist_list *next = tail->next; - if (compare_token_lists (tail->tokens, tokens)) { - if (prev) - prev->next = next; - else - hp->value = tail->next; - free_token_list (tail->tokens); - Safe_free (tail); - } else { - prev = tail; - } - tail = next; - } - } - } - - CPP_SET_WRITTEN (pfile, symstart); /* Pop */ - return 0; - error: - CPP_SET_WRITTEN (pfile, symstart); /* Pop */ - skip_rest_of_line (pfile); - return 1; -} - -/* Test whether there is an assertion named NAME - and optionally whether it has an asserted token list TOKENS. - NAME is not null terminated; its length is SYM_LENGTH. - If TOKENS_SPECIFIED is 0, then don't check for any token list. */ - -int -check_assertion ( - cpp_reader *pfile, - U_CHAR *name, - int sym_length, - int tokens_specified, - struct arglist *tokens) -{ - ASSERTION_HASHNODE *hp; - int hashcode = hashf (name, sym_length, ASSERTION_HASHSIZE); - - if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p) - cpp_pedwarn (pfile, "ANSI C does not allow testing assertions"); - - hp = assertion_lookup (pfile, name, sym_length, hashcode); - if (hp == NULL) - /* It is not an assertion; just return false. */ - return 0; - - /* If no token list was specified, then value is 1. */ - if (! tokens_specified) - return 1; - - { - struct tokenlist_list *tail; - - tail = hp->value; - - /* If a list of tokens was given, - then succeed if the assertion records a matching list. */ - - while (tail) { - if (compare_token_lists (tail->tokens, tokens)) - return 1; - tail = tail->next; - } - - /* Fail if the assertion has no matching list. */ - return 0; - } -} - -/* Compare two lists of tokens for equality including order of tokens. */ - -static int -compare_token_lists ( - struct arglist *l1, struct arglist *l2 ) -{ - while (l1 && l2) { - if (l1->length != l2->length) - return 0; - if (strncmp (l1->name, l2->name, l1->length)) - return 0; - l1 = l1->next; - l2 = l2->next; - } - - /* Succeed if both lists end at the same time. */ - return l1 == l2; -} - -struct arglist * -reverse_token_list ( - struct arglist *tokens) -{ - register struct arglist *prev = 0, *this, *next; - for (this = tokens; this; this = next) - { - next = this->next; - this->next = prev; - prev = this; - } - return prev; -} - -/* Read a space-separated list of tokens ending in a close parenthesis. - Return a list of strings, in the order they were written. - (In case of error, return 0 and store -1 in *ERROR_FLAG.) */ - -static struct arglist * -read_token_list ( - cpp_reader *pfile, - int *error_flag) -{ - struct arglist *token_ptrs = 0; - int depth = 1; - int length; - - *error_flag = 0; - FORWARD (1); /* Skip '(' */ - - /* Loop over the assertion value tokens. */ - while (depth > 0) - { - struct arglist *temp; - long name_written = CPP_WRITTEN (pfile); - int c; - - cpp_skip_hspace (pfile); - - c = GETC (); - - /* Find the end of the token. */ - if (c == '(') - { - CPP_PUTC (pfile, c); - depth++; - } - else if (c == ')') - { - depth--; - if (depth == 0) - break; - CPP_PUTC (pfile, c); - } - else if (c == '"' || c == '\'') - { - FORWARD(-1); - cpp_get_token (pfile); - } - else if (c == '\n') - break; - else - { - while (c != EOF && ! is_space[c] && c != '(' && c != ')' - && c != '"' && c != '\'') - { - CPP_PUTC (pfile, c); - c = GETC(); - } - if (c != EOF) FORWARD(-1); - } - - length = CPP_WRITTEN (pfile) - name_written; - temp = (struct arglist *) - Safe_malloc (sizeof (struct arglist) + length + 1); - temp->name = (U_CHAR *) (temp + 1); - bcopy ((char *) (pfile->token_buffer + name_written), - (char *) temp->name, length); - temp->name[length] = 0; - temp->next = token_ptrs; - token_ptrs = temp; - temp->length = length; - - CPP_ADJUST_WRITTEN (pfile, -length); /* pop */ - - if (c == EOF || c == '\n') - { /* FIXME */ - cpp_error (pfile, - "unterminated token sequence following `#' operator"); - return 0; - } - } - - /* We accumulated the names in reverse order. - Now reverse them to get the proper order. */ - return reverse_token_list (token_ptrs); -} - -static void -free_token_list ( - struct arglist *tokens) -{ - while (tokens) { - struct arglist *next = tokens->next; - Safe_free (tokens->name); - Safe_free (tokens); - tokens = next; - } -} - -/* Get the file-mode and data size of the file open on FD - and store them in *MODE_POINTER and *SIZE_POINTER. */ - -static int -file_size_and_mode ( - int fd, - int *mode_pointer, - long int *size_pointer) -{ - struct stat sbuf; - - if (fstat (fd, &sbuf) < 0) return (-1); - if (mode_pointer) *mode_pointer = sbuf.st_mode; - if (size_pointer) *size_pointer = sbuf.st_size; - return 0; -} - -/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME, - retrying if necessary. Return a negative value if an error occurs, - otherwise return the actual number of bytes read, - which must be LEN unless end-of-file was reached. */ - -static int -safe_read ( - int desc, - char *ptr, - int len) -{ - int left = len; - while (left > 0) { - int nchars = read (desc, ptr, left); - if (nchars < 0) - { -#ifdef EINTR - if (errno == EINTR) - continue; -#endif - return nchars; - } - if (nchars == 0) - break; - ptr += nchars; - left -= nchars; - } - return len - left; -} - -static char * -savestring ( - char *input) -{ - unsigned size = strlen (input); - char *output = Safe_malloc (size + 1); - strcpy (output, input); - return output; -} - -/* Initialize PMARK to remember the current position of PFILE. */ -void -parse_set_mark ( - struct parse_marker *pmark, - cpp_reader *pfile) -{ - cpp_buffer *pbuf = CPP_BUFFER (pfile); - pmark->next = pbuf->marks; - pbuf->marks = pmark; - pmark->buf = pbuf; - pmark->position = pbuf->cur - pbuf->buf; -} - -/* Cleanup PMARK - we no longer need it. */ -void -parse_clear_mark ( - struct parse_marker *pmark) -{ - struct parse_marker **pp = &pmark->buf->marks; - for (; ; pp = &(*pp)->next) { - if (*pp == NULL) fatal ("internal error", "in parse_set_mark"); - if (*pp == pmark) break; - } - *pp = pmark->next; -} - -/* Backup the current position of PFILE to that saved in PMARK. */ - -void -parse_goto_mark ( - struct parse_marker *pmark, - cpp_reader *pfile) -{ - cpp_buffer *pbuf = CPP_BUFFER (pfile); - if (pbuf != pmark->buf) - fatal ("internal error %s", "parse_goto_mark"); - pbuf->cur = pbuf->buf + pmark->position; -} - -/* Reset PMARK to point to the current position of PFILE. (Same - as parse_clear_mark (PMARK), parse_set_mark (PMARK, PFILE) but faster. */ - -void -parse_move_mark ( - struct parse_marker *pmark, - cpp_reader *pfile) -{ - cpp_buffer *pbuf = CPP_BUFFER (pfile); - if (pbuf != pmark->buf) - fatal ("internal error %s", "parse_move_mark"); - pmark->position = pbuf->cur - pbuf->buf; -} - -int -cpp_read_check_assertion ( - cpp_reader *pfile) -{ - int name_start = CPP_WRITTEN (pfile); - int name_length, name_written; - int result; - FORWARD (1); /* Skip '#' */ - cpp_skip_hspace (pfile); - parse_name (pfile, GETC ()); - name_written = CPP_WRITTEN (pfile); - name_length = name_written - name_start; - cpp_skip_hspace (pfile); - if (CPP_BUF_PEEK (CPP_BUFFER (pfile)) == '(') - { - int error_flag; - struct arglist *token_ptrs = read_token_list (pfile, &error_flag); - result = check_assertion (pfile, - pfile->token_buffer + name_start, name_length, - 1, token_ptrs); - } - else - result = check_assertion (pfile, - pfile->token_buffer + name_start, name_length, - 0, (struct arglist *)NULL_PTR); - CPP_ADJUST_WRITTEN (pfile, - name_length); /* pop */ - return result; -} - -void -cpp_print_file_and_line (pfile) - cpp_reader *pfile; -{ - cpp_buffer *ip = cpp_file_buffer (pfile); - - if (ip != NULL) - { - long line, col; - cpp_buf_line_and_col (ip, &line, &col); - cpp_file_line_for_message (pfile, ip->nominal_fname, - line, pfile->show_column ? col : -1); - } -} - -void -cpp_error (pfile, msg, arg1, arg2, arg3) - cpp_reader *pfile; - char *msg; - char *arg1, *arg2, *arg3; -{ - cpp_print_containing_files (pfile); - cpp_print_file_and_line (pfile); - cpp_message (pfile, 1, msg, arg1, arg2, arg3); -} - -/* Print error message but don't count it. */ - -void -cpp_warning (pfile, msg, arg1, arg2, arg3) - cpp_reader *pfile; - char *msg; - char *arg1, *arg2, *arg3; -{ - if (CPP_OPTIONS (pfile)->inhibit_warnings) - return; - - if (CPP_OPTIONS (pfile)->warnings_are_errors) - pfile->errors++; - - cpp_print_containing_files (pfile); - cpp_print_file_and_line (pfile); - cpp_message (pfile, 0, msg, arg1, arg2, arg3); -} - -/* Print an error message and maybe count it. */ - -void -cpp_pedwarn (pfile, msg, arg1, arg2, arg3) - cpp_reader *pfile; - char *msg; - char *arg1, *arg2, *arg3; -{ - if (CPP_OPTIONS (pfile)->pedantic_errors) - cpp_error (pfile, msg, arg1, arg2, arg3); - else - cpp_warning (pfile, msg, arg1, arg2, arg3); -} - -void -cpp_error_with_line (pfile, line, column, msg, arg1, arg2, arg3) - cpp_reader *pfile; - int line, column; - char *msg; - char *arg1, *arg2, *arg3; -{ - cpp_buffer *ip = cpp_file_buffer (pfile); - - cpp_print_containing_files (pfile); - - if (ip != NULL) - cpp_file_line_for_message (pfile, ip->nominal_fname, line, column); - - cpp_message (pfile, 1, msg, arg1, arg2, arg3); -} - -static void -cpp_warning_with_line (pfile, line, column, msg, arg1, arg2, arg3) - cpp_reader *pfile; - int line, column; - char *msg; - char *arg1, *arg2, *arg3; -{ - cpp_buffer *ip; - - if (CPP_OPTIONS (pfile)->inhibit_warnings) - return; - - if (CPP_OPTIONS (pfile)->warnings_are_errors) - pfile->errors++; - - cpp_print_containing_files (pfile); - - ip = cpp_file_buffer (pfile); - - if (ip != NULL) - cpp_file_line_for_message (pfile, ip->nominal_fname, line, column); - - cpp_message (pfile, 0, msg, arg1, arg2, arg3); -} - -void -cpp_pedwarn_with_line (pfile, line, column, msg, arg1, arg2, arg3) - cpp_reader *pfile; - int line; - char *msg; - char *arg1, *arg2, *arg3; -{ - if (CPP_OPTIONS (pfile)->pedantic_errors) - cpp_error_with_line (pfile, column, line, msg, arg1, arg2, arg3); - else - cpp_warning_with_line (pfile, line, column, msg, arg1, arg2, arg3); -} - -/* Report a warning (or an error if pedantic_errors) - giving specified file name and line number, not current. */ - -void -cpp_pedwarn_with_file_and_line (pfile, file, line, msg, arg1, arg2, arg3) - cpp_reader *pfile; - char *file; - int line; - char *msg; - char *arg1, *arg2, *arg3; -{ - if (!CPP_OPTIONS (pfile)->pedantic_errors - && CPP_OPTIONS (pfile)->inhibit_warnings) - return; - if (file != NULL) - cpp_file_line_for_message (pfile, file, line, -1); - cpp_message (pfile, CPP_OPTIONS (pfile)->pedantic_errors, - msg, arg1, arg2, arg3); -} - -/* This defines "errno" properly for VMS, and gives us EACCES. */ -#include -#ifndef errno -extern int errno; -#endif - -#ifndef VMS -#ifndef HAVE_STRERROR -extern int sys_nerr; -#if defined(bsd4_4) -extern const char *const sys_errlist[]; -#else -#if !defined(linux) -extern char *sys_errlist[]; -#endif -#endif -#else /* HAVE_STRERROR */ -char *strerror (); -#endif -#else /* VMS */ -char *strerror (int,...); -#endif - -/* - * my_strerror - return the descriptive text associated with an `errno' code. - */ - -char * -my_strerror (errnum) - int errnum; -{ - char *result; - -#ifndef VMS -#ifndef HAVE_STRERROR - result = (char *) ((errnum < sys_nerr) ? sys_errlist[errnum] : 0); -#else - result = strerror (errnum); -#endif -#else /* VMS */ - /* VAXCRTL's strerror() takes an optional second argument, which only - matters when the first argument is EVMSERR. However, it's simplest - just to pass it unconditionally. `vaxc$errno' is declared in - , and maintained by the library in parallel with `errno'. - We assume that caller's `errnum' either matches the last setting of - `errno' by the library or else does not have the value `EVMSERR'. */ - - result = strerror (errnum, vaxc$errno); -#endif - - if (!result) - result = "undocumented I/O error"; - - return result; -} - -/* Error including a message from `errno'. */ - -void -cpp_error_from_errno ( - cpp_reader *pfile, - char *name) -{ - cpp_buffer *ip = cpp_file_buffer (pfile); - - cpp_print_containing_files (pfile); - - if (ip != NULL) - cpp_file_line_for_message (pfile, ip->nominal_fname, ip->lineno, -1); - - cpp_message (pfile, 1, "%s: %s", name, my_strerror (errno),NULL); -} - -void -cpp_perror_with_name ( - cpp_reader *pfile, - char *name) -{ - cpp_message (pfile, 1, "%s: %s: %s", progname, name, my_strerror (errno)); -} - -/* TODO: - * No pre-compiled header file support. - * - * Possibly different enum token codes for each C/C++ token. - * - * Should clean up remaining directives to that do_XXX functions - * only take two arguments and all have command_reads_line. - * - * Find and cleanup remaining uses of static variables, - * - * Support for trigraphs. - * - * Support -dM flag (dump_all_macros). - * - * Support for_lint flag. - */ diff --git a/support/cpp/cpplib.h b/support/cpp/cpplib.h deleted file mode 100644 index e14d6834..00000000 --- a/support/cpp/cpplib.h +++ /dev/null @@ -1,681 +0,0 @@ -/* Definitions for CPP library. - Copyright (C) 1995 Free Software Foundation, Inc. - Written by Per Bothner, 1994-95. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! */ - -#include -#include -#define EMACS -#ifdef __cplusplus -extern "C" { -#endif - -#define STATIC_BUFFERS - -typedef unsigned char U_CHAR; - -struct parse_file; -typedef struct cpp_reader cpp_reader; -typedef struct cpp_buffer cpp_buffer; -typedef struct cpp_options cpp_options; -typedef struct hashnode cpp_hashnode; - -enum cpp_token { - CPP_EOF = -1, - CPP_OTHER = 0, - CPP_COMMENT = 1, - CPP_HSPACE, - CPP_VSPACE, /* newlines and #line directives */ - CPP_NAME, - CPP_NUMBER, - CPP_CHAR, - CPP_STRING, - CPP_DIRECTIVE, - CPP_LPAREN, /* "(" */ - CPP_RPAREN, /* ")" */ - CPP_LBRACE, /* "{" */ - CPP_RBRACE, /* "}" */ - CPP_COMMA, /* "," */ - CPP_SEMICOLON,/* ";" */ - CPP_3DOTS, /* "..." */ -#if 0 - CPP_ANDAND, /* "&&" */ - CPP_OROR, /* "||" */ - CPP_LSH, /* "<<" */ - CPP_RSH, /* ">>" */ - CPP_EQL, /* "==" */ - CPP_NEQ, /* "!=" */ - CPP_LEQ, /* "<=" */ - CPP_GEQ, /* ">=" */ - CPP_PLPL, /* "++" */ - CPP_MINMIN, /* "--" */ -#endif - /* POP_TOKEN is returned when we've popped a cpp_buffer. */ - CPP_POP -}; - -#ifndef PARAMS -#ifdef __STDC -#define PARAMS(P) P -#else -#define PARAMS(P) () -#endif -#endif /* !PARAMS */ - -typedef enum cpp_token (*parse_underflow_t) PARAMS((cpp_reader*)); -typedef int (*parse_cleanup_t) PARAMS((cpp_buffer *, cpp_reader*)); - -/* A parse_marker indicates a previous position, - which we can backtrack to. */ - -struct parse_marker { - cpp_buffer *buf; - struct parse_marker *next; - int position; -}; - -extern void parse_set_mark PARAMS ((struct parse_marker*, cpp_reader*)); -extern void parse_clear_mark PARAMS ((struct parse_marker*)); -extern void parse_goto_mark PARAMS((struct parse_marker*, cpp_reader*)); -extern void parse_move_mark PARAMS((struct parse_marker*, cpp_reader*)); - -extern int cpp_handle_options PARAMS ((cpp_reader*, int, char**)); -extern enum cpp_token cpp_get_token PARAMS ((struct parse_marker*)); -extern void cpp_skip_hspace PARAMS((cpp_reader*)); -extern enum cpp_token cpp_get_non_space_token PARAMS ((cpp_reader *)); -extern int cpp_read_check_assertion (cpp_reader *pfile) ; - -/* Maintain and search list of included files, for #import. */ - -#define IMPORT_HASH_SIZE 31 - -struct import_file { - char *name; - ino_t inode; - dev_t dev; - struct import_file *next; -}; - -/* If we have a huge buffer, may need to cache more recent counts */ -#define CPP_LINE_BASE(BUF) ((BUF)->buf + (BUF)->line_base) - -struct cpp_buffer { - unsigned char *buf; - unsigned char *cur; - unsigned char *rlimit; /* end of valid data */ - unsigned char *alimit; /* end of allocated buffer */ - unsigned char *prev; /* start of current token */ - - char *fname; - /* Filename specified with #line command. */ - char *nominal_fname; - - /* Record where in the search path this file was found. - For #include_next. */ - struct file_name_list *dir; - - long line_base; - long lineno; /* Line number at CPP_LINE_BASE. */ - long colno; /* Column number at CPP_LINE_BASE. */ -#ifndef STATIC_BUFFERS - cpp_buffer *chain; -#endif - parse_underflow_t underflow; - parse_cleanup_t cleanup; - void *data; - struct parse_marker *marks; - /* Value of if_stack at start of this file. - Used to prohibit unmatched #endif (etc) in an include file. */ - struct if_stack *if_stack; - - /* True if this is a header file included using . */ - char system_header_p; - char seen_eof; - - /* True if buffer contains escape sequences. - Currently there are are only two kind: - "@-" means following identifier should not be macro-expanded. - "@ " means a token-separator. This turns into " " in final output - if not stringizing and needed to separate tokens; otherwise nothing. - "@@" means a normal '@'. - (An '@' inside a string stands for itself and is never an escape.) */ - char has_escapes; -}; - -struct cpp_pending; /* Forward declaration - for C++. */ -struct file_name_map_list; - -typedef struct assertion_hashnode ASSERTION_HASHNODE; -#define ASSERTION_HASHSIZE 37 - -#ifdef STATIC_BUFFERS -/* Maximum nesting of cpp_buffers. We use a static limit, partly for - efficiency, and partly to limit runaway recursion. */ -#define CPP_STACK_MAX 200 -#endif - -struct cpp_reader { - unsigned char *limit; - parse_underflow_t get_token; - cpp_buffer *buffer; -#ifdef STATIC_BUFFERS - cpp_buffer buffer_stack[CPP_STACK_MAX]; -#endif - - int errors; /* Error counter for exit code */ - void *data; - - U_CHAR *token_buffer; - int token_buffer_size; - - /* Line where a newline was first seen in a string constant. */ - int multiline_string_line; - - /* Current depth in #include directives that use <...>. */ - int system_include_depth; - - /* List of included files that contained #pragma once. */ - struct file_name_list *dont_repeat_files; - - /* List of other included files. - If ->control_macro if nonzero, the file had a #ifndef - around the entire contents, and ->control_macro gives the macro name. */ - struct file_name_list *all_include_files; - - /* Current maximum length of directory names in the search path - for include files. (Altered as we get more of them.) */ - int max_include_len; - - /* Hash table of files already included with #include or #import. */ - struct import_file *import_hash_table[IMPORT_HASH_SIZE]; - - struct if_stack *if_stack; - - /* Nonzero means we are inside an IF during a -pcp run. In this mode - macro expansion is done, and preconditions are output for all macro - uses requiring them. */ - char pcp_inside_if; - - /* Nonzero means we have printed (while error reporting) a list of - containing files that matches the current status. */ - char input_stack_listing_current; - - /* If non-zero, macros are not expanded. */ - char no_macro_expand; - - /* Print column number in error messages. */ - char show_column; - - /* We're printed a warning recommending against using #import. */ - char import_warning; - - /* If true, character between '<' and '>' are a single (string) token. */ - char parsing_include_directive; - - /* True if escape sequences (as described for has_escapes in - parse_buffer) should be emitted. */ - char output_escapes; - - /* 0: Have seen non-white-space on this line. - 1: Only seen white space so far on this line. - 2: Only seen white space so far in this file. */ - char only_seen_white; - - /* Nonzero means this file was included with a -imacros or -include - command line and should not be recorded as an include file. */ - - int no_record_file; - - long lineno; - - struct tm *timebuf; - - ASSERTION_HASHNODE *assertion_hashtab[ASSERTION_HASHSIZE]; - - /* Buffer of -M output. */ - char *deps_buffer; - - /* Number of bytes allocated in above. */ - int deps_allocated_size; - - /* Number of bytes used. */ - int deps_size; - - /* Number of bytes since the last newline. */ - int deps_column; -}; - -#define CPP_BUF_PEEK(BUFFER) \ - ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur : EOF) -#define CPP_BUF_GET(BUFFER) \ - ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF) -#define CPP_FORWARD(BUFFER, N) ((BUFFER)->cur += (N)) - -/* Number of characters currently in PFILE's output buffer. */ -#define CPP_WRITTEN(PFILE) ((PFILE)->limit - (PFILE)->token_buffer) -#define CPP_PWRITTEN(PFILE) ((PFILE)->limit) - -/* Make sure PFILE->token_buffer has space for at least N more characters. */ -#define CPP_RESERVE(PFILE, N) \ - ((int) (CPP_WRITTEN (PFILE) + N) > (PFILE)->token_buffer_size \ - && (cpp_grow_buffer (PFILE, N), 0)) - -/* Append string STR (of length N) to PFILE's output buffer. - Assume there is enough space. */ -#define CPP_PUTS_Q(PFILE, STR, N) \ - (bcopy (STR, (PFILE)->limit, (N)), (PFILE)->limit += (N)) -/* Append string STR (of length N) to PFILE's output buffer. Make space. */ -#define CPP_PUTS(PFILE, STR, N) CPP_RESERVE(PFILE, N), CPP_PUTS_Q(PFILE, STR,N) -/* Append character CH to PFILE's output buffer. Assume sufficient space. */ -#define CPP_PUTC_Q(PFILE, CH) (*(PFILE)->limit++ = (CH)) -/* Append character CH to PFILE's output buffer. Make space if need be. */ -#define CPP_PUTC(PFILE, CH) (CPP_RESERVE (PFILE, 1), CPP_PUTC_Q (PFILE, CH)) -/* Make sure PFILE->limit is followed by '\0'. */ -#define CPP_NUL_TERMINATE_Q(PFILE) (*(PFILE)->limit = 0) -#define CPP_NUL_TERMINATE(PFILE) (CPP_RESERVE(PFILE, 1), *(PFILE)->limit = 0) -#define CPP_ADJUST_WRITTEN(PFILE,DELTA) ((PFILE)->limit += (DELTA)) -#define CPP_SET_WRITTEN(PFILE,N) ((PFILE)->limit = (PFILE)->token_buffer + (N)) - -#define CPP_OPTIONS(PFILE) ((cpp_options*)(PFILE)->data) -#define CPP_BUFFER(PFILE) ((PFILE)->buffer) -#ifdef STATIC_BUFFERS -#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)+1) -#define CPP_NULL_BUFFER(PFILE) (&(PFILE)->buffer_stack[CPP_STACK_MAX]) -#else -#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->chain) -#define CPP_NULL_BUFFER(PFILE) ((cpp_buffer*)0) -#endif - -/* Pointed to by parse_file::data. */ -struct cpp_options { - char *in_fname; - - /* Name of output file, for error messages. */ - char *out_fname; - - struct file_name_map_list *map_list; - - /* Non-0 means -v, so print the full set of include dirs. */ - char verbose; - - /* Nonzero means use extra default include directories for C++. */ - - char cplusplus; - - /* Nonzero means handle cplusplus style comments */ - - char cplusplus_comments; - - /* Nonzero means handle #import, for objective C. */ - - char objc; - - /* Nonzero means this is an assembly file, and allow - unknown directives, which could be comments. */ - - int lang_asm; - - /* Nonzero means turn NOTREACHED into #pragma NOTREACHED etc */ - - char for_lint; - - /* Nonzero means handle CHILL comment syntax - and output CHILL string delimiter for __DATE___ etc. */ - - char chill; - - /* Nonzero means copy comments into the output file. */ - - char put_out_comments; - - /* Nonzero means don't process the ANSI trigraph sequences. */ - - char no_trigraphs; - - /* Nonzero means print the names of included files rather than - the preprocessed output. 1 means just the #include "...", - 2 means #include <...> as well. */ - - char print_deps; - - /* Nonzero if missing .h files in -M output are assumed to be generated - files and not errors. */ - - char print_deps_missing_files; - - /* If true, fopen (deps_file, "a") else fopen (deps_file, "w"). */ - char print_deps_append; - - /* Nonzero means print names of header files (-H). */ - - char print_include_names; - - /* Nonzero means try to make failure to fit ANSI C an error. */ - - char pedantic_errors; - - /* Nonzero means don't print warning messages. -w. */ - - char inhibit_warnings; - - /* Nonzero means warn if slash-star appears in a comment. */ - - char warn_comments; - - /* Nonzero means warn if there are any trigraphs. */ - - char warn_trigraphs; - - /* Nonzero means warn if #import is used. */ - - char warn_import; - - /* Nonzero means warn if a macro argument is (or would be) - stringified with -traditional. */ - - char warn_stringify; - - /* Nonzero means turn warnings into errors. */ - - char warnings_are_errors; - - /* Nonzero causes output not to be done, - but directives such as #define that have side effects - are still obeyed. */ - - char no_output; - - /* Nonzero means don't output line number information. */ - - char no_line_commands; - -/* Nonzero means output the text in failing conditionals, - inside #failed ... #endfailed. */ - - char output_conditionals; - - /* Nonzero means -I- has been seen, - so don't look for #include "foo" the source-file directory. */ - char ignore_srcdir; - -/* Zero means dollar signs are punctuation. - -$ stores 0; -traditional may store 1. Default is 1 for VMS, 0 otherwise. - This must be 0 for correct processing of this ANSI C program: - #define foo(a) #a - #define lose(b) foo (b) - #define test$ - lose (test) */ - char dollars_in_ident; -#ifndef DOLLARS_IN_IDENTIFIERS -#define DOLLARS_IN_IDENTIFIERS 1 -#endif - - /* Nonzero means try to imitate old fashioned non-ANSI preprocessor. */ - char traditional; - - /* Nonzero means give all the error messages the ANSI standard requires. */ - char pedantic; - - char done_initializing; - - struct file_name_list *include; /* First dir to search */ - /* First dir to search for */ - /* This is the first element to use for #include <...>. - If it is 0, use the entire chain for such includes. */ - struct file_name_list *first_bracket_include; - /* This is the first element in the chain that corresponds to - a directory of system header files. */ - struct file_name_list *first_system_include; - struct file_name_list *last_include; /* Last in chain */ - - /* Chain of include directories to put at the end of the other chain. */ - struct file_name_list *after_include; - struct file_name_list *last_after_include; /* Last in chain */ - - /* Chain to put at the start of the system include files. */ - struct file_name_list *before_system; - struct file_name_list *last_before_system; /* Last in chain */ - - /* Directory prefix that should replace `/usr' in the standard - include file directories. */ - char *include_prefix; - - char inhibit_predefs; - char no_standard_includes; - char no_standard_cplusplus_includes; - -/* dump_only means inhibit output of the preprocessed text - and instead output the definitions of all user-defined - macros in a form suitable for use as input to cccp. - dump_names means pass #define and the macro name through to output. - dump_definitions means pass the whole definition (plus #define) through -*/ - - enum {dump_none = 0, dump_only, dump_names, dump_definitions} - dump_macros; - -/* Nonzero means pass all #define and #undef directives which we actually - process through to the output stream. This feature is used primarily - to allow cc1 to record the #defines and #undefs for the sake of - debuggers which understand about preprocessor macros, but it may - also be useful with -E to figure out how symbols are defined, and - where they are defined. */ - int debug_output; - - /* Pending -D, -U and -A options, in reverse order. */ - struct cpp_pending *pending; - - /* File name which deps are being written to. - This is 0 if deps are being written to stdout. */ - char *deps_file; - - /* Target-name to write with the dependency information. */ - char *deps_target; -}; - -#define CPP_TRADITIONAL(PFILE) (CPP_OPTIONS(PFILE)-> traditional) -#define CPP_PEDANTIC(PFILE) (CPP_OPTIONS (PFILE)->pedantic) -#define CPP_PRINT_DEPS(PFILE) (CPP_OPTIONS (PFILE)->print_deps) - -/* Name under which this program was invoked. */ - -extern char *progname; - -/* The structure of a node in the hash table. The hash table - has entries for all tokens defined by #define commands (type T_MACRO), - plus some special tokens like __LINE__ (these each have their own - type, and the appropriate code is run when that type of node is seen. - It does not contain control words like "#define", which are recognized - by a separate piece of code. */ - -/* different flavors of hash nodes --- also used in keyword table */ -enum node_type { - T_DEFINE = 1, /* the `#define' keyword */ - T_INCLUDE, /* the `#include' keyword */ - T_INCLUDE_NEXT, /* the `#include_next' keyword */ - T_IMPORT, /* the `#import' keyword */ - T_IFDEF, /* the `#ifdef' keyword */ - T_IFNDEF, /* the `#ifndef' keyword */ - T_IF, /* the `#if' keyword */ - T_ELSE, /* `#else' */ - T_PRAGMA, /* `#pragma' */ - T_ELIF, /* `#elif' */ - T_UNDEF, /* `#undef' */ - T_LINE, /* `#line' */ - T_ERROR, /* `#error' */ - T_WARNING, /* `#warning' */ - T_ENDIF, /* `#endif' */ - T_SCCS, /* `#sccs', used on system V. */ - T_IDENT, /* `#ident', used on system V. */ - T_ASSERT, /* `#assert', taken from system V. */ - T_UNASSERT, /* `#unassert', taken from system V. */ - T_SPECLINE, /* special symbol `__LINE__' */ - T_DATE, /* `__DATE__' */ - T_FILE, /* `__FILE__' */ - T_BASE_FILE, /* `__BASE_FILE__' */ - T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */ - T_VERSION, /* `__VERSION__' */ - T_SIZE_TYPE, /* `__SIZE_TYPE__' */ - T_PTRDIFF_TYPE, /* `__PTRDIFF_TYPE__' */ - T_WCHAR_TYPE, /* `__WCHAR_TYPE__' */ - T_USER_LABEL_PREFIX_TYPE, /* `__USER_LABEL_PREFIX__' */ - T_REGISTER_PREFIX_TYPE, /* `__REGISTER_PREFIX__' */ - T_TIME, /* `__TIME__' */ - T_CONST, /* Constant value, used by `__STDC__' */ - T_MACRO, /* macro defined by `#define' */ - T_DISABLED, /* macro temporarily turned off for rescan */ - T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */ - T_PCSTRING, /* precompiled string (hashval is KEYDEF *) */ - T_UNUSED /* Used for something not defined. */ - }; - -/* Structure returned by create_definition */ -typedef struct macrodef MACRODEF; -struct macrodef -{ - struct definition *defn; - U_CHAR *symnam; - int symlen; -}; - -/* Structure allocated for every #define. For a simple replacement - such as - #define foo bar , - nargs = -1, the `pattern' list is null, and the expansion is just - the replacement text. Nargs = 0 means a functionlike macro with no args, - e.g., - #define getchar() getc (stdin) . - When there are args, the expansion is the replacement text with the - args squashed out, and the reflist is a list describing how to - build the output from the input: e.g., "3 chars, then the 1st arg, - then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg". - The chars here come from the expansion. Whatever is left of the - expansion after the last arg-occurrence is copied after that arg. - Note that the reflist can be arbitrarily long--- - its length depends on the number of times the arguments appear in - the replacement text, not how many args there are. Example: - #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and - pattern list - { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL } - where (x, y) means (nchars, argno). */ - -typedef struct definition DEFINITION; -struct definition { - int nargs; - int length; /* length of expansion string */ - int predefined; /* True if the macro was builtin or */ - /* came from the command line */ - U_CHAR *expansion; - int line; /* Line number of definition */ - char *file; /* File of definition */ - char rest_args; /* Nonzero if last arg. absorbs the rest */ - struct reflist { - struct reflist *next; - char stringify; /* nonzero if this arg was preceded by a - # operator. */ - char raw_before; /* Nonzero if a ## operator before arg. */ - char raw_after; /* Nonzero if a ## operator after arg. */ - char rest_args; /* Nonzero if this arg. absorbs the rest */ - int nchars; /* Number of literal chars to copy before - this arg occurrence. */ - int argno; /* Number of arg to substitute (origin-0) */ - } *pattern; - union { - /* Names of macro args, concatenated in reverse order - with comma-space between them. - The only use of this is that we warn on redefinition - if this differs between the old and new definitions. */ - U_CHAR *argnames; - } args; -}; - -extern U_CHAR is_idchar[256]; - -/* Stack of conditionals currently in progress - (including both successful and failing conditionals). */ - -struct if_stack { - struct if_stack *next; /* for chaining to the next stack frame */ - char *fname; /* copied from input when frame is made */ - int lineno; /* similarly */ - int if_succeeded; /* true if a leg of this if-group - has been passed through rescan */ - U_CHAR *control_macro; /* For #ifndef at start of file, - this is the macro name tested. */ - enum node_type type; /* type of last directive seen in this group */ -}; -typedef struct if_stack IF_STACK_FRAME; - -extern void cpp_buf_line_and_col PARAMS((cpp_buffer*, long*, long*)); -extern cpp_buffer* cpp_file_buffer PARAMS((cpp_reader*)); -extern void cpp_define PARAMS ((cpp_reader*, U_CHAR*)); - -extern void cpp_error (); -extern void cpp_warning (); -extern void cpp_pedwarn (); -extern void cpp_error_with_line (); -extern void cpp_pedwarn_with_line (); -extern void cpp_pedwarn_with_file_and_line (); -extern void fatal (); -extern void cpp_error_from_errno (); -extern void cpp_perror_with_name (); -extern void cpp_pfatal_with_name (); - -extern void cpp_grow_buffer PARAMS ((cpp_reader*, long)); -extern int cpp_parse_escape PARAMS ((cpp_reader*, char**)); -extern cpp_buffer* cpp_push_buffer PARAMS ((cpp_reader *, U_CHAR*, long)); -extern cpp_buffer* cpp_pop_buffer PARAMS ((cpp_reader *)); - -extern cpp_hashnode* cpp_lookup PARAMS ((cpp_reader*, const U_CHAR*, - int, int)); - -/* Define the MS VC6 stuff - Some of these should also be defined for -the other hosts but they are here until declared safe for all */ - -#if 1 // defined(_MSC_VER) - -void init_parse_file (cpp_reader *pfile) ; - -void init_parse_options (struct cpp_options *opts) ; - -int push_parse_file (cpp_reader *pfile,char *fname) ; - -void cpp_finish (cpp_reader *pfile) ; - -void cpp_hash_cleanup (cpp_reader *pfile) ; - -void cpp_file_line_for_message (cpp_reader *pfile,char *filename ,int line, int column) ; - -void cpp_print_containing_files (cpp_reader *pfile) ; - -void cpp_message (cpp_reader *pfile,int is_error,char *msg,char *arg1, char *arg2, char *arg3) ; - -void skip_rest_of_line (cpp_reader *pfile) ; - -/* Parse an identifier starting with C. */ - -int parse_name (cpp_reader *pfile, int c) ; - -#endif - - -#ifdef __cplusplus -} -#endif diff --git a/support/cpp/cppmain.c b/support/cpp/cppmain.c deleted file mode 100644 index cb9ab534..00000000 --- a/support/cpp/cppmain.c +++ /dev/null @@ -1,105 +0,0 @@ -/* CPP main program, using CPP Library. - Copyright (C) 1995 Free Software Foundation, Inc. - Written by Per Bothner, 1994-95. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! */ - -#include "cpplib.h" -#include -#include -#include - -#define SUCCESS_EXIT_CODE 0 -#define FATAL_EXIT_CODE 33 -#define EMACS -#ifndef EMACS -#include "config.h" -#endif /* not EMACS */ - -extern char *getenv (); -char *version_string = " for SDC51"; -char *progname; - -cpp_reader parse_in; -cpp_options options; - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - - -int -main (argc, argv) - int argc; - char **argv; -{ - char *p; - int i; - int argi = 1; /* Next argument to handle. */ - struct cpp_options *opts = &options; - - p = argv[0] + strlen (argv[0]); - while (p != argv[0] && p[-1] != '/') --p; - progname = p; - - init_parse_file (&parse_in); - parse_in.data = opts; - - init_parse_options (opts); - - argi += cpp_handle_options (&parse_in, argc - argi , argv + argi); - if (argi < argc) - fatal ("Invalid option `%s'", argv[argi]); - parse_in.show_column = 1; - - i = push_parse_file (&parse_in, opts->in_fname); - if (i != SUCCESS_EXIT_CODE) - return i; - - /* Now that we know the input file is valid, open the output. */ - - if (!opts->out_fname || !strcmp (opts->out_fname, "")) - opts->out_fname = "stdout"; - else if (! freopen (opts->out_fname, "w", stdout)) - cpp_pfatal_with_name (&parse_in, opts->out_fname); - - for (;;) - { - enum cpp_token kind; - if (! opts->no_output) - { - fwrite (parse_in.token_buffer, 1, CPP_WRITTEN (&parse_in), stdout); - } - parse_in.limit = parse_in.token_buffer; - kind = cpp_get_token (&parse_in); - if (kind == CPP_EOF) - break; - } - - cpp_finish (&parse_in); - - if (parse_in.errors) - exit (FATAL_EXIT_CODE); - exit (SUCCESS_EXIT_CODE); -} diff --git a/support/cpp/i386/386bsd.h b/support/cpp/i386/386bsd.h deleted file mode 100644 index cdab5f57..00000000 --- a/support/cpp/i386/386bsd.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Configuration for an i386 running 386BSD as the target machine. */ - -/* This is tested by i386gas.h. */ -#define YES_UNDERSCORES - -#include "i386/gstabs.h" - -/* Get perform_* macros to build libgcc.a. */ -#include "i386/perform.h" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dunix -Di386 -D____386BSD____ -D__386BSD__ -DBSD_NET2 -Asystem(unix) -Asystem(bsd) -Acpu(i386) -Amachine(i386)" - -/* Like the default, except no -lg. */ -#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}" - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "int" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "short unsigned int" - -#define WCHAR_UNSIGNED 1 - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 16 - -/* 386BSD does have atexit. */ - -#define HAVE_ATEXIT - -/* Redefine this to use %eax instead of %edx. */ -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) \ -{ \ - if (flag_pic) \ - { \ - fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%eax\n", \ - LPREFIX, (LABELNO)); \ - fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \ - } \ - else \ - { \ - fprintf (FILE, "\tmovl $%sP%d,%%eax\n", LPREFIX, (LABELNO)); \ - fprintf (FILE, "\tcall mcount\n"); \ - } \ -} - -/* There are conflicting reports about whether this system uses - a different assembler syntax. wilson@cygnus.com says # is right. */ -#undef COMMENT_BEGIN -#define COMMENT_BEGIN "#" - -#undef ASM_APP_ON -#define ASM_APP_ON "#APP\n" - -#undef ASM_APP_OFF -#define ASM_APP_OFF "#NO_APP\n" - -/* The following macros are stolen from i386v4.h */ -/* These have to be defined to get PIC code correct */ - -/* This is how to output an element of a case-vector that is relative. - This is only used for PIC code. See comments by the `casesi' insn in - i386.md for an explanation of the expression this outputs. */ - -#undef ASM_OUTPUT_ADDR_DIFF_ELT -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ - fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE) - -/* Indicate that jump tables go in the text section. This is - necessary when compiling PIC code. */ - -#define JUMP_TABLES_IN_TEXT_SECTION - -/* Don't default to pcc-struct-return, because gcc is the only compiler, and - we want to retain compatibility with older gcc versions. */ -#define DEFAULT_PCC_STRUCT_RETURN 0 diff --git a/support/cpp/i386/aix386.h b/support/cpp/i386/aix386.h deleted file mode 100644 index e0498e79..00000000 --- a/support/cpp/i386/aix386.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Definitions for IBM PS2 running AIX/386 with gas. - From: Minh Tran-Le - Copyright (C) 1988 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* - * This configuration file is for gcc with gas-2.x and gnu ld 2.x - * with aix ps/2 1.3.x. - */ - -/* Define USE_GAS if you have the new version of gas that can handle - * multiple segments and .section pseudo op. This will allow gcc to - * use the .init section for g++ ctor/dtor. - * - * If you don't have gas then undefined USE_GAS. You will also have - * to use collect if you want to use g++ - */ -#define USE_GAS - -#include "i386/aix386ng.h" - -/* Use crt1.o as a startup file and crtn.o as a closing file. - And add crtbegin.o and crtend.o for ctors and dtors */ - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC \ - "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}} crtbegin.o%s" -#undef ENDFILE_SPEC -#define ENDFILE_SPEC \ - "crtend.o%s crtn.o%s" - -/* Removed the -K flags because the gnu ld does not handle it */ -#undef LINK_SPEC -#define LINK_SPEC "%{T*} %{z:-lm}" - -/* Define a few machine-specific details of the implementation of - constructors. */ - -#undef INIT_SECTION_ASM_OP -#define INIT_SECTION_ASM_OP ".section .init,\"x\"" - -#define CTOR_LIST_BEGIN \ - asm (INIT_SECTION_ASM_OP); \ - asm ("pushl $0") -#define CTOR_LIST_END CTOR_LIST_BEGIN - -#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ - do { \ - init_section (); \ - fprintf (FILE, "\tpushl $"); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) diff --git a/support/cpp/i386/aix386ng.h b/support/cpp/i386/aix386ng.h deleted file mode 100644 index 5d09fc30..00000000 --- a/support/cpp/i386/aix386ng.h +++ /dev/null @@ -1,143 +0,0 @@ -/* Definitions for IBM PS2 running AIX/386. - From: Minh Tran-Le - Copyright (C) 1988 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#include "i386/i386.h" - -/* Get the generic definitions for system V.3. */ - -#include "svr3.h" - -/* Use the ATT assembler syntax. - This overrides at least one macro (ASM_OUTPUT_LABELREF) from svr3.h. */ - -#include "i386/att.h" - -/* Use crt1.o as a startup file and crtn.o as a closing file. */ - -#define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}" -#define ENDFILE_SPEC "crtn.o%s" - -#define LIB_SPEC "%{shlib:-lc_s} -lc" - -/* Special flags for the linker. I don't know what they do. */ - -#define LINK_SPEC "%{K} %{!K:-K} %{T*} %{z:-lm}" - -/* Specify predefined symbols in preprocessor. */ - -#define CPP_PREDEFINES "-Dps2 -Dunix -Di386 -Asystem(unix) -Asystem(aix) -Acpu(i386) -Amachine(i386)" - -#define CPP_SPEC \ - "%{posix:-D_POSIX_SOURCE}%{!posix:-DAIX} -D_I386 -D_AIX -D_MBCS" - -/* special flags for the aix assembler to generate the short form for all - qualifying forward reference */ -/* The buggy /bin/as of aix ps/2 1.2.x cannot always handle it. */ -#if 0 -#define ASM_SPEC "-s2" -#endif /* 0 */ - -#undef ASM_FILE_START -#define ASM_FILE_START(FILE) \ - do { fprintf (FILE, "\t.file\t"); \ - output_quoted_string (FILE, dump_base_name); \ - fprintf (FILE, "\n"); \ - if (optimize) \ - ASM_FILE_START_1 (FILE); \ - else \ - fprintf (FILE, "\t.noopt\n"); \ - } while (0) - -/* This was suggested, but it shouldn't be right for DBX output. -- RMS - #define ASM_OUTPUT_SOURCE_FILENAME(FILE, NAME) */ - -/* Writing `int' for a bitfield forces int alignment for the structure. */ - -#define PCC_BITFIELD_TYPE_MATTERS 1 - -#ifndef USE_GAS -/* Don't write a `.optim' pseudo; this assembler - is said to have a bug when .optim is used. */ - -#undef ASM_FILE_START_1 -#define ASM_FILE_START_1(FILE) fprintf (FILE, "\t.noopt\n") -#endif - -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. */ - -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) \ - fprintf (FILE, "\tleal %sP%d,%%eax\n\tcall mcount\n", LPREFIX, (LABELNO)); - -/* Note that using bss_section here caused errors - in building shared libraries on system V.3. - but AIX 1.2 does not have yet shareable libraries on PS2 */ -#undef ASM_OUTPUT_LOCAL -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ - (bss_section (), \ - ASM_OUTPUT_LABEL ((FILE), (NAME)), \ - fprintf ((FILE), "\t.set .,.+%u\n", (ROUNDED))) - - -/* Undef all the .init and .fini section stuff if we are not using gas and - * gnu ld so that we can use collect because the standard /bin/as and /bin/ld - * cannot handle those. - */ -#ifndef USE_GAS -# undef INIT_SECTION_ASM_OP -# undef FINI_SECTION_ASM_OP -# undef CTORS_SECTION_ASM_OP -# undef DTORS_SECTION_ASM_OP -# undef ASM_OUTPUT_CONSTRUCTOR -# undef ASM_OUTPUT_DESTRUCTOR -# undef DO_GLOBAL_CTORS_BODY - -# undef CTOR_LIST_BEGIN -# define CTOR_LIST_BEGIN -# undef CTOR_LIST_END -# define CTOR_LIST_END -# undef DTOR_LIST_BEGIN -# define DTOR_LIST_BEGIN -# undef DTOR_LIST_END -# define DTOR_LIST_END - -# undef CONST_SECTION_FUNCTION -# define CONST_SECTION_FUNCTION \ -void \ -const_section () \ -{ \ - extern void text_section(); \ - text_section(); \ -} - -# undef EXTRA_SECTION_FUNCTIONS -# define EXTRA_SECTION_FUNCTIONS \ - CONST_SECTION_FUNCTION \ - BSS_SECTION_FUNCTION - -/* for collect2 */ -# define OBJECT_FORMAT_COFF -# define MY_ISCOFF(magic) \ - ((magic) == I386MAGIC || (magic) == I386SVMAGIC) - -#endif /* !USE_GAS */ diff --git a/support/cpp/i386/att.h b/support/cpp/i386/att.h deleted file mode 100644 index f8bbb764..00000000 --- a/support/cpp/i386/att.h +++ /dev/null @@ -1,106 +0,0 @@ -/* Definitions for AT&T assembler syntax for the Intel 80386. - Copyright (C) 1988 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Include common aspects of all 386 Unix assemblers. */ -#include "i386/unix.h" - -#define TARGET_VERSION fprintf (stderr, " (80386, ATT syntax)"); - -/* Define the syntax of instructions and addresses. */ - -/* Prefix for internally generated assembler labels. */ -#define LPREFIX ".L" - -/* Assembler pseudos to introduce constants of various size. */ - -/* #define ASM_BYTE_OP "\t.byte" Now in svr3.h or svr4.h. */ -#define ASM_SHORT "\t.value" -#define ASM_LONG "\t.long" -#define ASM_DOUBLE "\t.double" - -/* How to output an ASCII string constant. */ - -#define ASM_OUTPUT_ASCII(FILE, p, size) \ -do \ -{ int i = 0; \ - while (i < (size)) \ - { if (i%10 == 0) { if (i!=0) fprintf ((FILE), "\n"); \ - fprintf ((FILE), "%s ", ASM_BYTE_OP); } \ - else fprintf ((FILE), ","); \ - fprintf ((FILE), "0x%x", ((p)[i++] & 0377)) ;} \ - fprintf ((FILE), "\n"); \ -} while (0) - -/* Do use .optim by default on this machine. */ -#undef ASM_FILE_START_1 -#define ASM_FILE_START_1(FILE) fprintf (FILE, "\t.optim\n") - -/* This is how to output an assembler line - that says to advance the location counter - to a multiple of 2**LOG bytes. */ - -#define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG)) - -/* This is how to output an assembler line - that says to advance the location counter by SIZE bytes. */ - -#define ASM_OUTPUT_SKIP(FILE,SIZE) \ - fprintf ((FILE), "\t.set .,.+%u\n", (SIZE)) - -/* Can't use ASM_OUTPUT_SKIP in text section; it doesn't leave 0s. */ - -#define ASM_NO_SKIP_IN_TEXT 1 - -#undef BSS_SECTION_FUNCTION /* Override the definition from svr3.h. */ -#define BSS_SECTION_FUNCTION \ -void \ -bss_section () \ -{ \ - if (in_section != in_bss) \ - { \ - fprintf (asm_out_file, "%s\n", BSS_SECTION_ASM_OP); \ - in_section = in_bss; \ - } \ -} - -/* Define the syntax of labels and symbol definitions/declarations. */ - -/* This is how to store into the string BUF - the symbol_ref name of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. */ - -#undef ASM_GENERATE_INTERNAL_LABEL -#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ - sprintf ((BUF), ".%s%d", (PREFIX), (NUMBER)) - -/* This is how to output an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. */ - -#undef ASM_OUTPUT_INTERNAL_LABEL -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - fprintf (FILE, ".%s%d:\n", PREFIX, NUM) - -/* This is how to output a reference to a user-level label named NAME. */ - -#undef ASM_OUTPUT_LABELREF -#define ASM_OUTPUT_LABELREF(FILE,NAME) \ - fprintf (FILE, "%s", NAME) diff --git a/support/cpp/i386/bsd.h b/support/cpp/i386/bsd.h deleted file mode 100644 index 6bf7399d..00000000 --- a/support/cpp/i386/bsd.h +++ /dev/null @@ -1,130 +0,0 @@ -/* Definitions for BSD assembler syntax for Intel 386 - (actually AT&T syntax for insns and operands, - adapted to BSD conventions for symbol names and debugging.) - Copyright (C) 1988 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Include common aspects of all 386 Unix assemblers. */ -#include "i386/unix.h" - -/* Use the Sequent Symmetry assembler syntax. */ - -#define TARGET_VERSION fprintf (stderr, " (80386, BSD syntax)"); - -/* Define the syntax of pseudo-ops, labels and comments. */ - -/* Prefix for internally generated assembler labels. If we aren't using - underscores, we are using prefix `.'s to identify labels that should - be ignored, as in `i386/gas.h' --karl@cs.umb.edu */ -#ifdef NO_UNDERSCORES -#define LPREFIX ".L" -#else -#define LPREFIX "L" -#endif /* not NO_UNDERSCORES */ - -/* Assembler pseudos to introduce constants of various size. */ - -#define ASM_BYTE_OP "\t.byte" -#define ASM_SHORT "\t.word" -#define ASM_LONG "\t.long" -#define ASM_DOUBLE "\t.double" - -/* Output at beginning of assembler file. - ??? I am skeptical of this -- RMS. */ - -#define ASM_FILE_START(FILE) \ - do { fprintf (FILE, "\t.file\t"); \ - output_quoted_string (FILE, dump_base_name); \ - fprintf (FILE, "\n"); \ - } while (0) - -/* This was suggested, but it shouldn't be right for DBX output. -- RMS - #define ASM_OUTPUT_SOURCE_FILENAME(FILE, NAME) */ - - -/* Define the syntax of labels and symbol definitions/declarations. */ - -/* This is how to output an assembler line - that says to advance the location counter by SIZE bytes. */ - -#define ASM_OUTPUT_SKIP(FILE,SIZE) \ - fprintf (FILE, "\t.space %u\n", (SIZE)) - -/* Define the syntax of labels and symbol definitions/declarations. */ - -/* This says how to output an assembler line - to define a global common symbol. */ - -#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ -( fputs (".comm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%u\n", (ROUNDED))) - -/* This says how to output an assembler line - to define a local common symbol. */ - -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ -( fputs (".lcomm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%u\n", (ROUNDED))) - -/* This is how to output an assembler line - that says to advance the location counter - to a multiple of 2**LOG bytes. */ - -#define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", (LOG)) - -/* This is how to store into the string BUF - the symbol_ref name of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. */ - -#ifdef NO_UNDERSCORES -#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ - sprintf ((BUF), "*.%s%d", (PREFIX), (NUMBER)) -#else -#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ - sprintf ((BUF), "*%s%d", (PREFIX), (NUMBER)) -#endif - -/* This is how to output an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. */ - -#ifdef NO_UNDERSCORES -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - fprintf (FILE, ".%s%d:\n", PREFIX, NUM) -#else -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - fprintf (FILE, "%s%d:\n", PREFIX, NUM) -#endif - -/* This is how to output a reference to a user-level label named NAME. */ - -#ifdef NO_UNDERSCORES -#define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "%s", NAME) -#else -#define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "_%s", NAME) -#endif /* not NO_UNDERSCORES */ - -/* Sequent has some changes in the format of DBX symbols. */ -#define DBX_NO_XREFS 1 - -/* Don't split DBX symbols into continuations. */ -#define DBX_CONTIN_LENGTH 0 diff --git a/support/cpp/i386/bsd386.h b/support/cpp/i386/bsd386.h deleted file mode 100644 index 935a2e06..00000000 --- a/support/cpp/i386/bsd386.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Configuration for an i386 running BSDI's BSD/386 1.1 as the target - machine. */ - -#include "i386/386bsd.h" - -/* We exist mostly to add -Dbsdi and such to the predefines. */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dunix -Di386 -Dbsdi -D__i386__ -D__bsdi__ -D____386BSD____ -D__386BSD__ -DBSD_NET2 -Asystem(unix) -Asystem(bsd) -Acpu(i386) -Amachine(i386)" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "int" - -#undef WCHAR_UNSIGNED -#define WCHAR_UNSIGNED 0 - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 32 diff --git a/support/cpp/i386/config-nt.sed b/support/cpp/i386/config-nt.sed deleted file mode 100644 index 6c86b27e..00000000 --- a/support/cpp/i386/config-nt.sed +++ /dev/null @@ -1,38 +0,0 @@ -/^Makefile/,/^ rm -f config.run/d -s/rm -f/del/ -s/|| cp/|| copy/ -/^config.status/,/ fi/d -s/config.status//g -s/\/dev\/null/NUL/g -s/$(srcdir)\/c-parse/c-parse/g -s/$(srcdir)\/c-gperf/c-gperf/g -/^multilib.h/ s/multilib/not-multilib/ -/^target=/ c\ -target=winnt3.5 -/^xmake_file=/ d -/^tmake_file=/ d -/^out_file/ c\ -out_file=config/i386/i386.c -/^out_object_file/ c\ -out_object_file=i386.obj -/^md_file/ c\ -md_file=config/i386/i386.md -/^tm_file/ c\ -tm_file=config/i386/win-nt.h -/^build_xm_file/ c\ -build_xm_file=config/i386/xm-winnt.h -/^host_xm_file/ c\ -host_xm_file=config/i386/xm-winnt.h -/^####target/ i\ -CC = cl \ -CLIB = libc.lib kernel32.lib \ -CFLAGS = -Di386 -DWIN32 -D_WIN32 -D_M_IX86=300 -D_X86_=1 \\\ - -DALMOST_STDC -D_MSC_VER=800 \ -LDFLAGS = -align:0x1000 -subsystem:console -entry:mainCRTStartup \\\ - -stack:1000000,1000 \ -\ -EXTRA_OBJS=winnt.obj \ -winnt.obj: $(srcdir)/config/i386/winnt.c \ -\ $(CC) $(CFLAGS) \\\ -\ -I. -I$(srcdir) -I$(srcdir)/config -c $(srcdir)/config/i386/winnt.c \ - diff --git a/support/cpp/i386/freebsd.h b/support/cpp/i386/freebsd.h deleted file mode 100644 index c4e9991c..00000000 --- a/support/cpp/i386/freebsd.h +++ /dev/null @@ -1,250 +0,0 @@ -/* Definitions of target machine for GNU compiler for Intel 80386 - running FreeBSD. - Copyright (C) 1988, 1992, 1994 Free Software Foundation, Inc. - Contributed by Poul-Henning Kamp - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This goes away when the math-emulator is fixed */ -#define TARGET_CPU_DEFAULT 0400 /* TARGET_NO_FANCY_MATH_387 */ - -/* This is tested by i386gas.h. */ -#define YES_UNDERSCORES - -/* Don't assume anything about the header files. */ -#define NO_IMPLICIT_EXTERN_C - -#include "i386/gstabs.h" - -/* Get perform_* macros to build libgcc.a. */ -#include "i386/perform.h" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dunix -Di386 -D__FreeBSD__ -D__386BSD__ -Asystem(unix) -Asystem(FreeBSD) -Acpu(i386) -Amachine(i386)" - -/* Like the default, except no -lg. */ -#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}" - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "int" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "short unsigned int" - -#define WCHAR_UNSIGNED 1 - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 16 - -#define HAVE_ATEXIT - -/* There are conflicting reports about whether this system uses - a different assembler syntax. wilson@cygnus.com says # is right. */ -#undef COMMENT_BEGIN -#define COMMENT_BEGIN "#" - -#undef ASM_APP_ON -#define ASM_APP_ON "#APP\n" - -#undef ASM_APP_OFF -#define ASM_APP_OFF "#NO_APP\n" - -/* The following macros are stolen from i386v4.h */ -/* These have to be defined to get PIC code correct */ - -/* This is how to output an element of a case-vector that is relative. - This is only used for PIC code. See comments by the `casesi' insn in - i386.md for an explanation of the expression this outputs. */ - -#undef ASM_OUTPUT_ADDR_DIFF_ELT -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ - fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE) - -/* Indicate that jump tables go in the text section. This is - necessary when compiling PIC code. */ - -#define JUMP_TABLES_IN_TEXT_SECTION - -/* Don't default to pcc-struct-return, because gcc is the only compiler, and - we want to retain compatibility with older gcc versions. */ -#define DEFAULT_PCC_STRUCT_RETURN 0 - -/* Profiling routines, partially copied from i386/osfrose.h. */ - -/* Redefine this to use %eax instead of %edx. */ -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) \ -{ \ - if (flag_pic) \ - { \ - fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%eax\n", \ - LPREFIX, (LABELNO)); \ - fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \ - } \ - else \ - { \ - fprintf (FILE, "\tmovl $%sP%d,%%eax\n", LPREFIX, (LABELNO)); \ - fprintf (FILE, "\tcall mcount\n"); \ - } \ -} - -/* - * Some imports from svr4.h in support of shared libraries. - * Currently, we need the DECLARE_OBJECT_SIZE stuff. - */ - -/* Define the strings used for the special svr4 .type and .size directives. - These strings generally do not vary from one system running svr4 to - another, but if a given system (e.g. m88k running svr) needs to use - different pseudo-op names for these, they may be overridden in the - file which includes this one. */ - -#define TYPE_ASM_OP ".type" -#define SIZE_ASM_OP ".size" - -/* The following macro defines the format used to output the second - operand of the .type assembler directive. Different svr4 assemblers - expect various different forms for this operand. The one given here - is just a default. You may need to override it in your machine- - specific tm.h file (depending upon the particulars of your assembler). */ - -#define TYPE_OPERAND_FMT "@%s" - -/* Write the extra assembler code needed to declare a function's result. - Most svr4 assemblers don't require any special declaration of the - result value, but there are exceptions. */ - -#ifndef ASM_DECLARE_RESULT -#define ASM_DECLARE_RESULT(FILE, RESULT) -#endif - -/* These macros generate the special .type and .size directives which - are used to set the corresponding fields of the linker symbol table - entries in an ELF object file under SVR4. These macros also output - the starting labels for the relevant functions/objects. */ - -/* Write the extra assembler code needed to declare a function properly. - Some svr4 assemblers need to also have something extra said about the - function's return value. We allow for that here. */ - -#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ - do { \ - fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (FILE, NAME); \ - putc (',', FILE); \ - fprintf (FILE, TYPE_OPERAND_FMT, "function"); \ - putc ('\n', FILE); \ - ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ - ASM_OUTPUT_LABEL(FILE, NAME); \ - } while (0) - -/* Write the extra assembler code needed to declare an object properly. */ - -#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ - do { \ - fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (FILE, NAME); \ - putc (',', FILE); \ - fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ - putc ('\n', FILE); \ - size_directive_output = 0; \ - if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \ - { \ - size_directive_output = 1; \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ - } \ - ASM_OUTPUT_LABEL(FILE, NAME); \ - } while (0) - -/* Output the size directive for a decl in rest_of_decl_compilation - in the case where we did not do so before the initializer. - Once we find the error_mark_node, we know that the value of - size_directive_output was set - by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ - -#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ -do { \ - char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ - if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \ - && ! AT_END && TOP_LEVEL \ - && DECL_INITIAL (DECL) == error_mark_node \ - && !size_directive_output) \ - { \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, name); \ - fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL)));\ - } \ - } while (0) - - -/* This is how to declare the size of a function. */ - -#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ - do { \ - if (!flag_inhibit_size_directive) \ - { \ - char label[256]; \ - static int labelno; \ - labelno++; \ - ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \ - ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, (FNAME)); \ - fprintf (FILE, ","); \ - assemble_name (FILE, label); \ - fprintf (FILE, "-"); \ - assemble_name (FILE, (FNAME)); \ - putc ('\n', FILE); \ - } \ - } while (0) - -#define ASM_SPEC " %| %{fpic:-k} %{fPIC:-k}" -#define LINK_SPEC \ - "%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} %{assert*}" - -/* This is defined when gcc is compiled in the BSD-directory-tree, and must - * make up for the gap to all the stuff done in the GNU-makefiles. - */ - -#ifdef FREEBSD_NATIVE - -#define INCLUDE_DEFAULTS { \ - { "/usr/include", 0 }, \ - { "/usr/include/g++", 1 }, \ - { 0, 0} \ - } - -#undef MD_EXEC_PREFIX -#define MD_EXEC_PREFIX "/usr/libexec/" - -#undef STANDARD_STARTFILE_PREFIX -#define STANDARD_STARTFILE_PREFIX "/usr/lib" - -#if 0 /* This is very wrong!!! */ -#define DEFAULT_TARGET_MACHINE "i386-unknown-freebsd_1.0" -#define GPLUSPLUS_INCLUDE_DIR "/usr/local/lib/gcc-lib/i386-unknown-freebsd_1.0/2.5.8/include" -#define TOOL_INCLUDE_DIR "/usr/local/i386-unknown-freebsd_1.0/include" -#define GCC_INCLUDE_DIR "/usr/local/lib/gcc-lib/i386-unknown-freebsd_1.0/2.5.8/include" -#endif - -#endif /* FREEBSD_NATIVE */ diff --git a/support/cpp/i386/gas.h b/support/cpp/i386/gas.h deleted file mode 100644 index d0201572..00000000 --- a/support/cpp/i386/gas.h +++ /dev/null @@ -1,155 +0,0 @@ -/* Definitions for Intel 386 running system V with gnu tools - Copyright (C) 1988, 1993, 1994 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Note that i386/seq-gas.h is a GAS configuration that does not use this - file. */ - -#include "i386/i386.h" - -#ifndef YES_UNDERSCORES -/* Define this now, because i386/bsd.h tests it. */ -#define NO_UNDERSCORES -#endif - -/* Use the bsd assembler syntax. */ -/* we need to do this because gas is really a bsd style assembler, - * and so doesn't work well this these att-isms: - * - * ASM_OUTPUT_SKIP is .set .,.+N, which isn't implemented in gas - * ASM_OUTPUT_LOCAL is done with .set .,.+N, but that can't be - * used to define bss static space - * - * Next is the question of whether to uses underscores. RMS didn't - * like this idea at first, but since it is now obvious that we - * need this separate tm file for use with gas, at least to get - * dbx debugging info, I think we should also switch to underscores. - * We can keep i386v for real att style output, and the few - * people who want both form will have to compile twice. - */ - -#include "i386/bsd.h" - -/* these come from i386/bsd.h, but are specific to sequent */ -#undef DBX_NO_XREFS -#undef DBX_CONTIN_LENGTH - -/* Ask for COFF symbols. */ - -#define SDB_DEBUGGING_INFO - -/* Specify predefined symbols in preprocessor. */ - -#define CPP_PREDEFINES "-Dunix -Di386 -Asystem(unix) -Acpu(i386) -Amachine(i386)" -#define CPP_SPEC "%{posix:-D_POSIX_SOURCE}" - -/* Allow #sccs in preprocessor. */ - -#define SCCS_DIRECTIVE - -/* Output #ident as a .ident. */ - -#define ASM_OUTPUT_IDENT(FILE, NAME) fprintf (FILE, "\t.ident \"%s\"\n", NAME); - -/* Implicit library calls should use memcpy, not bcopy, etc. */ - -#define TARGET_MEM_FUNCTIONS - -#if 0 /* People say gas uses the log as the arg to .align. */ -/* When using gas, .align N aligns to an N-byte boundary. */ - -#undef ASM_OUTPUT_ALIGN -#define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG)) -#endif - -/* Align labels, etc. at 4-byte boundaries. - For the 486, align to 16-byte boundary for sake of cache. */ - -#undef ASM_OUTPUT_ALIGN_CODE -#define ASM_OUTPUT_ALIGN_CODE(FILE) \ - fprintf ((FILE), "\t.align %d,0x90\n", i386_align_jumps) - -/* Align start of loop at 4-byte boundary. */ - -#undef ASM_OUTPUT_LOOP_ALIGN -#define ASM_OUTPUT_LOOP_ALIGN(FILE) \ - fprintf ((FILE), "\t.align %d,0x90\n", i386_align_loops) - - -/* A C statement or statements which output an assembler instruction - opcode to the stdio stream STREAM. The macro-operand PTR is a - variable of type `char *' which points to the opcode name in its - "internal" form--the form that is written in the machine description. - - GAS version 1.38.1 doesn't understand the `repz' opcode mnemonic. - So use `repe' instead. */ - -#define ASM_OUTPUT_OPCODE(STREAM, PTR) \ -{ \ - if ((PTR)[0] == 'r' \ - && (PTR)[1] == 'e' \ - && (PTR)[2] == 'p') \ - { \ - if ((PTR)[3] == 'z') \ - { \ - fprintf (STREAM, "repe"); \ - (PTR) += 4; \ - } \ - else if ((PTR)[3] == 'n' && (PTR)[4] == 'z') \ - { \ - fprintf (STREAM, "repne"); \ - (PTR) += 5; \ - } \ - } \ -} - -/* Define macro used to output shift-double opcodes when the shift - count is in %cl. Some assemblers require %cl as an argument; - some don't. - - GAS requires the %cl argument, so override i386/unix.h. */ - -#undef AS3_SHIFT_DOUBLE -#define AS3_SHIFT_DOUBLE(a,b,c,d) AS3 (a,b,c,d) - -/* Print opcodes the way that GAS expects them. */ -#define GAS_MNEMONICS 1 - -#ifdef NO_UNDERSCORES /* If user-symbols don't have underscores, - then it must take more than `L' to identify - a label that should be ignored. */ - -/* This is how to store into the string BUF - the symbol_ref name of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. */ - -#undef ASM_GENERATE_INTERNAL_LABEL -#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ - sprintf ((BUF), ".%s%d", (PREFIX), (NUMBER)) - -/* This is how to output an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. */ - -#undef ASM_OUTPUT_INTERNAL_LABEL -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - fprintf (FILE, ".%s%d:\n", PREFIX, NUM) - -#endif /* NO_UNDERSCORES */ diff --git a/support/cpp/i386/gnu.h b/support/cpp/i386/gnu.h deleted file mode 100644 index 1ad5df99..00000000 --- a/support/cpp/i386/gnu.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Configuration for an i386 running GNU with ELF as the target machine. */ - -/* This does it mostly for us. */ -#include - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES GNU_CPP_PREDEFINES("i386") - -#undef LINK_SPEC -#define LINK_SPEC "-m elf_i386 %{shared:-shared} \ - %{!shared: \ - %{!ibcs: \ - %{!static: \ - %{rdynamic:-export-dynamic} \ - %{!dynamic-linker:-dynamic-linker /lib/ld.so} \ - %{!rpath:-rpath /lib/}} %{static:-static}}}" - - -/* Get machine-independent configuration parameters for the GNU system. */ -#include diff --git a/support/cpp/i386/go32.h b/support/cpp/i386/go32.h deleted file mode 100644 index 5618a0dd..00000000 --- a/support/cpp/i386/go32.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Configuration for an i386 running MS-DOS with djgpp/go32. */ - -/* Don't assume anything about the header files. */ -#define NO_IMPLICIT_EXTERN_C - -#define HANDLE_SYSV_PRAGMA - -#define YES_UNDERSCORES - -#include "i386/gas.h" - -#ifdef CPP_PREDEFINES -#undef CPP_PREDEFINES -#endif -#define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DMSDOS \ - -Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386)" - -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_ctor, in_dtor - -#undef EXTRA_SECTION_FUNCTIONS -#define EXTRA_SECTION_FUNCTIONS \ - CTOR_SECTION_FUNCTION \ - DTOR_SECTION_FUNCTION - -#define CTOR_SECTION_FUNCTION \ -void \ -ctor_section () \ -{ \ - if (in_section != in_ctor) \ - { \ - fprintf (asm_out_file, "\t.section .ctor\n"); \ - in_section = in_ctor; \ - } \ -} - -#define DTOR_SECTION_FUNCTION \ -void \ -dtor_section () \ -{ \ - if (in_section != in_dtor) \ - { \ - fprintf (asm_out_file, "\t.section .dtor\n"); \ - in_section = in_dtor; \ - } \ -} - -#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ - do { \ - ctor_section (); \ - fprintf (FILE, "%s\t", ASM_LONG); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) - -#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ - do { \ - dtor_section (); \ - fprintf (FILE, "%s\t", ASM_LONG); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) - - diff --git a/support/cpp/i386/gstabs.h b/support/cpp/i386/gstabs.h deleted file mode 100644 index 5f0ae348..00000000 --- a/support/cpp/i386/gstabs.h +++ /dev/null @@ -1,9 +0,0 @@ -#include "i386/gas.h" - -/* We do not want to output SDB debugging information. */ - -#undef SDB_DEBUGGING_INFO - -/* We want to output DBX debugging information. */ - -#define DBX_DEBUGGING_INFO diff --git a/support/cpp/i386/i386-aout.h b/support/cpp/i386/i386-aout.h deleted file mode 100644 index e4be8d5d..00000000 --- a/support/cpp/i386/i386-aout.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Definitions for "naked" Intel 386 using a.out (or coff encap'd - a.out) object format and stabs debugging info. - - Copyright (C) 1994 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* This is tested by gas.h. */ -#define YES_UNDERSCORES - -#include "i386/gstabs.h" - -/* Specify predefined symbols in preprocessor. */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Di386" - -/* end of i386-aout.h */ diff --git a/support/cpp/i386/i386-coff.h b/support/cpp/i386/i386-coff.h deleted file mode 100644 index 915e307d..00000000 --- a/support/cpp/i386/i386-coff.h +++ /dev/null @@ -1,97 +0,0 @@ -/* Definitions for "naked" Intel 386 using coff object format files - and coff debugging info. - - Copyright (C) 1994 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#include "i386/gas.h" - -/* Specify predefined symbols in preprocessor. */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Di386" - -#undef DBX_DEBUGGING_INFO -#define SDB_DEBUGGING_INFO - -/* Support the ctors and dtors sections for g++. */ - -#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"x\"" -#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"x\"" - -/* A list of other sections which the compiler might be "in" at any - given time. */ - -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_ctors, in_dtors - -/* A list of extra section function definitions. */ - -#undef EXTRA_SECTION_FUNCTIONS -#define EXTRA_SECTION_FUNCTIONS \ - CTORS_SECTION_FUNCTION \ - DTORS_SECTION_FUNCTION - -#define CTORS_SECTION_FUNCTION \ -void \ -ctors_section () \ -{ \ - if (in_section != in_ctors) \ - { \ - fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \ - in_section = in_ctors; \ - } \ -} - -#define DTORS_SECTION_FUNCTION \ -void \ -dtors_section () \ -{ \ - if (in_section != in_dtors) \ - { \ - fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \ - in_section = in_dtors; \ - } \ -} - -#define INT_ASM_OP ".long" - -/* A C statement (sans semicolon) to output an element in the table of - global constructors. */ -#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ - do { \ - ctors_section (); \ - fprintf (FILE, "\t%s\t ", INT_ASM_OP); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) - -/* A C statement (sans semicolon) to output an element in the table of - global destructors. */ -#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ - do { \ - dtors_section (); \ - fprintf (FILE, "\t%s\t ", INT_ASM_OP); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) - - -/* end of i386-coff.h */ diff --git a/support/cpp/i386/i386.c b/support/cpp/i386/i386.c deleted file mode 100644 index 48c58a09..00000000 --- a/support/cpp/i386/i386.c +++ /dev/null @@ -1,3245 +0,0 @@ -/* Subroutines for insn-output.c for Intel X86. - Copyright (C) 1988, 1992, 1994, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include -#include -#include -#include "config.h" -#include "rtl.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "real.h" -#include "insn-config.h" -#include "conditions.h" -#include "insn-flags.h" -#include "output.h" -#include "insn-attr.h" -#include "tree.h" -#include "flags.h" -#include "function.h" - -#ifdef EXTRA_CONSTRAINT -/* If EXTRA_CONSTRAINT is defined, then the 'S' - constraint in REG_CLASS_FROM_LETTER will no longer work, and various - asm statements that need 'S' for class SIREG will break. */ - error EXTRA_CONSTRAINT conflicts with S constraint letter -/* The previous line used to be #error, but some compilers barf - even if the conditional was untrue. */ -#endif - -#define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx)) - -extern FILE *asm_out_file; -extern char *strcat (); - -char *singlemove_string (); -char *output_move_const_single (); -char *output_fp_cc0_set (); - -char *hi_reg_name[] = HI_REGISTER_NAMES; -char *qi_reg_name[] = QI_REGISTER_NAMES; -char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES; - -/* Array of the smallest class containing reg number REGNO, indexed by - REGNO. Used by REGNO_REG_CLASS in i386.h. */ - -enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] = -{ - /* ax, dx, cx, bx */ - AREG, DREG, CREG, BREG, - /* si, di, bp, sp */ - SIREG, DIREG, INDEX_REGS, GENERAL_REGS, - /* FP registers */ - FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS, - FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, - /* arg pointer */ - INDEX_REGS -}; - -/* Test and compare insns in i386.md store the information needed to - generate branch and scc insns here. */ - -struct rtx_def *i386_compare_op0 = NULL_RTX; -struct rtx_def *i386_compare_op1 = NULL_RTX; -struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)(); - -/* Register allocation order */ -char *i386_reg_alloc_order; -static char regs_allocated[FIRST_PSEUDO_REGISTER]; - -/* # of registers to use to pass arguments. */ -char *i386_regparm_string; /* # registers to use to pass args */ -int i386_regparm; /* i386_regparm_string as a number */ - -/* Alignment to use for loops and jumps */ -char *i386_align_loops_string; /* power of two alignment for loops */ -char *i386_align_jumps_string; /* power of two alignment for non-loop jumps */ -char *i386_align_funcs_string; /* power of two alignment for functions */ - -int i386_align_loops; /* power of two alignment for loops */ -int i386_align_jumps; /* power of two alignment for non-loop jumps */ -int i386_align_funcs; /* power of two alignment for functions */ - - -/* Sometimes certain combinations of command options do not make - sense on a particular target machine. You can define a macro - `OVERRIDE_OPTIONS' to take account of this. This macro, if - defined, is executed once just after all the command options have - been parsed. - - Don't use this macro to turn on various extra optimizations for - `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */ - -void -override_options () -{ - int ch, i, regno; - char *p; - int def_align; - -#ifdef SUBTARGET_OVERRIDE_OPTIONS - SUBTARGET_OVERRIDE_OPTIONS; -#endif - - /* Validate registers in register allocation order */ - if (i386_reg_alloc_order) - { - for (i = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++) - { - switch (ch) - { - case 'a': regno = 0; break; - case 'd': regno = 1; break; - case 'c': regno = 2; break; - case 'b': regno = 3; break; - case 'S': regno = 4; break; - case 'D': regno = 5; break; - case 'B': regno = 6; break; - - default: fatal ("Register '%c' is unknown", ch); - } - - if (regs_allocated[regno]) - fatal ("Register '%c' was already specified in the allocation order", ch); - - regs_allocated[regno] = 1; - } - } - - /* Validate -mregparm= value */ - if (i386_regparm_string) - { - i386_regparm = atoi (i386_regparm_string); - if (i386_regparm < 0 || i386_regparm > REGPARM_MAX) - fatal ("-mregparm=%d is not between 0 and %d", i386_regparm, REGPARM_MAX); - } - - def_align = (TARGET_386) ? 2 : 4; - - /* Validate -malign-loops= value, or provide default */ - if (i386_align_loops_string) - { - i386_align_loops = atoi (i386_align_loops_string); - if (i386_align_loops < 0 || i386_align_loops > MAX_CODE_ALIGN) - fatal ("-malign-loops=%d is not between 0 and %d", - i386_align_loops, MAX_CODE_ALIGN); - } - else - i386_align_loops = 2; - - /* Validate -malign-jumps= value, or provide default */ - if (i386_align_jumps_string) - { - i386_align_jumps = atoi (i386_align_jumps_string); - if (i386_align_jumps < 0 || i386_align_jumps > MAX_CODE_ALIGN) - fatal ("-malign-jumps=%d is not between 0 and %d", - i386_align_jumps, MAX_CODE_ALIGN); - } - else - i386_align_jumps = def_align; - - /* Validate -malign-functions= value, or provide default */ - if (i386_align_funcs_string) - { - i386_align_funcs = atoi (i386_align_funcs_string); - if (i386_align_funcs < 0 || i386_align_funcs > MAX_CODE_ALIGN) - fatal ("-malign-functions=%d is not between 0 and %d", - i386_align_funcs, MAX_CODE_ALIGN); - } - else - i386_align_funcs = def_align; -} - -/* A C statement (sans semicolon) to choose the order in which to - allocate hard registers for pseudo-registers local to a basic - block. - - Store the desired register order in the array `reg_alloc_order'. - Element 0 should be the register to allocate first; element 1, the - next register; and so on. - - The macro body should not assume anything about the contents of - `reg_alloc_order' before execution of the macro. - - On most machines, it is not necessary to define this macro. */ - -void -order_regs_for_local_alloc () -{ - int i, ch, order, regno; - - /* User specified the register allocation order */ - if (i386_reg_alloc_order) - { - for (i = order = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++) - { - switch (ch) - { - case 'a': regno = 0; break; - case 'd': regno = 1; break; - case 'c': regno = 2; break; - case 'b': regno = 3; break; - case 'S': regno = 4; break; - case 'D': regno = 5; break; - case 'B': regno = 6; break; - } - - reg_alloc_order[order++] = regno; - } - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - { - if (!regs_allocated[i]) - reg_alloc_order[order++] = i; - } - } - - /* If users did not specify a register allocation order, favor eax - normally except if DImode variables are used, in which case - favor edx before eax, which seems to cause less spill register - not found messages. */ - else - { - rtx insn; - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - reg_alloc_order[i] = i; - - if (optimize) - { - int use_dca = FALSE; - - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - { - if (GET_CODE (insn) == INSN) - { - rtx set = NULL_RTX; - rtx pattern = PATTERN (insn); - - if (GET_CODE (pattern) == SET) - set = pattern; - - else if ((GET_CODE (pattern) == PARALLEL - || GET_CODE (pattern) == SEQUENCE) - && GET_CODE (XVECEXP (pattern, 0, 0)) == SET) - set = XVECEXP (pattern, 0, 0); - - if (set && GET_MODE (SET_SRC (set)) == DImode) - { - use_dca = TRUE; - break; - } - } - } - - if (use_dca) - { - reg_alloc_order[0] = 1; /* edx */ - reg_alloc_order[1] = 2; /* ecx */ - reg_alloc_order[2] = 0; /* eax */ - } - } - } -} - - -/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific - attribute for DECL. The attributes in ATTRIBUTES have previously been - assigned to DECL. */ - -int -i386_valid_decl_attribute_p (decl, attributes, identifier, args) - tree decl; - tree attributes; - tree identifier; - tree args; -{ - return 0; -} - -/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific - attribute for TYPE. The attributes in ATTRIBUTES have previously been - assigned to TYPE. */ - -int -i386_valid_type_attribute_p (type, attributes, identifier, args) - tree type; - tree attributes; - tree identifier; - tree args; -{ - if (TREE_CODE (type) != FUNCTION_TYPE - && TREE_CODE (type) != FIELD_DECL - && TREE_CODE (type) != TYPE_DECL) - return 0; - - /* Stdcall attribute says callee is responsible for popping arguments - if they are not variable. */ - if (is_attribute_p ("stdcall", identifier)) - return (args == NULL_TREE); - - /* Cdecl attribute says the callee is a normal C declaration */ - if (is_attribute_p ("cdecl", identifier)) - return (args == NULL_TREE); - - /* Regparm attribute specifies how many integer arguments are to be - passed in registers */ - if (is_attribute_p ("regparm", identifier)) - { - tree cst; - - if (!args || TREE_CODE (args) != TREE_LIST - || TREE_CHAIN (args) != NULL_TREE - || TREE_VALUE (args) == NULL_TREE) - return 0; - - cst = TREE_VALUE (args); - if (TREE_CODE (cst) != INTEGER_CST) - return 0; - - if (TREE_INT_CST_HIGH (cst) != 0 - || TREE_INT_CST_LOW (cst) < 0 - || TREE_INT_CST_LOW (cst) > REGPARM_MAX) - return 0; - - return 1; - } - - return 0; -} - -/* Return 0 if the attributes for two types are incompatible, 1 if they - are compatible, and 2 if they are nearly compatible (which causes a - warning to be generated). */ - -int -i386_comp_type_attributes (type1, type2) - tree type1; - tree type2; -{ - return 1; -} - - -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. - - On the 80386, the RTD insn may be used to pop them if the number - of args is fixed, but if the number is variable then the caller - must pop them all. RTD can't be used for library calls now - because the library is compiled with the Unix compiler. - Use of RTD is a selectable option, since it is incompatible with - standard Unix calling sequences. If the option is not selected, - the caller must always pop the args. - - The attribute stdcall is equivalent to RTD on a per module basis. */ - -int -i386_return_pops_args (fundecl, funtype, size) - tree fundecl; - tree funtype; - int size; -{ - int rtd = TARGET_RTD; - - if (TREE_CODE (funtype) == IDENTIFIER_NODE) - return 0; - - /* Cdecl functions override -mrtd, and never pop the stack */ - if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) - return 0; - - /* Stdcall functions will pop the stack if not variable args */ - if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype))) - rtd = 1; - - if (rtd) - { - if (TYPE_ARG_TYPES (funtype) == NULL_TREE - || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype))) == void_type_node)) - return size; - - if (aggregate_value_p (TREE_TYPE (funtype))) - return GET_MODE_SIZE (Pmode); - } - - return 0; -} - - -/* Argument support functions. */ - -/* Initialize a variable CUM of type CUMULATIVE_ARGS - for a call to a function whose data type is FNTYPE. - For a library call, FNTYPE is 0. */ - -void -init_cumulative_args (cum, fntype, libname) - CUMULATIVE_ARGS *cum; /* argument info to initialize */ - tree fntype; /* tree ptr for function decl */ - rtx libname; /* SYMBOL_REF of library name or 0 */ -{ - static CUMULATIVE_ARGS zero_cum; - tree param, next_param; - - if (TARGET_DEBUG_ARG) - { - fprintf (stderr, "\ninit_cumulative_args ("); - if (fntype) - { - tree ret_type = TREE_TYPE (fntype); - fprintf (stderr, "fntype code = %s, ret code = %s", - tree_code_name[ (int)TREE_CODE (fntype) ], - tree_code_name[ (int)TREE_CODE (ret_type) ]); - } - else - fprintf (stderr, "no fntype"); - - if (libname) - fprintf (stderr, ", libname = %s", XSTR (libname, 0)); - } - - *cum = zero_cum; - - /* Set up the number of registers to use for passing arguments. */ - cum->nregs = i386_regparm; - if (fntype) - { - tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype)); - if (attr) - cum->nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))); - } - - /* Determine if this function has variable arguments. This is - indicated by the last argument being 'void_type_mode' if there - are no variable arguments. If there are variable arguments, then - we won't pass anything in registers */ - - if (cum->nregs) - { - for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0; - param != (tree)0; - param = next_param) - { - next_param = TREE_CHAIN (param); - if (next_param == (tree)0 && TREE_VALUE (param) != void_type_node) - cum->nregs = 0; - } - } - - if (TARGET_DEBUG_ARG) - fprintf (stderr, ", nregs=%d )\n", cum->nregs); - - return; -} - -/* Update the data in CUM to advance over an argument - of mode MODE and data type TYPE. - (TYPE is null for libcalls where that information may not be available.) */ - -void -function_arg_advance (cum, mode, type, named) - CUMULATIVE_ARGS *cum; /* current arg information */ - enum machine_mode mode; /* current arg mode */ - tree type; /* type of the argument or 0 if lib support */ - int named; /* whether or not the argument was named */ -{ - int bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode); - int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; - - if (TARGET_DEBUG_ARG) - fprintf (stderr, - "function_adv( size=%d, words=%2d, nregs=%d, mode=%4s, named=%d )\n\n", - words, cum->words, cum->nregs, GET_MODE_NAME (mode), named); - - cum->words += words; - cum->nregs -= words; - cum->regno += words; - - if (cum->nregs <= 0) - { - cum->nregs = 0; - cum->regno = 0; - } - - return; -} - -/* Define where to put the arguments to a function. - Value is zero to push the argument on the stack, - or a hard register in which to store the argument. - - MODE is the argument's machine mode. - TYPE is the data type of the argument (as a tree). - This is null for libcalls where that information may - not be available. - CUM is a variable of type CUMULATIVE_ARGS which gives info about - the preceding args and about the function being called. - NAMED is nonzero if this argument is a named parameter - (otherwise it is an extra parameter matching an ellipsis). */ - -struct rtx_def * -function_arg (cum, mode, type, named) - CUMULATIVE_ARGS *cum; /* current arg information */ - enum machine_mode mode; /* current arg mode */ - tree type; /* type of the argument or 0 if lib support */ - int named; /* != 0 for normal args, == 0 for ... args */ -{ - rtx ret = NULL_RTX; - int bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode); - int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; - - switch (mode) - { - default: /* for now, pass fp/complex values on the stack */ - break; - - case BLKmode: - case DImode: - case SImode: - case HImode: - case QImode: - if (words <= cum->nregs) - ret = gen_rtx (REG, mode, cum->regno); - break; - } - - if (TARGET_DEBUG_ARG) - { - fprintf (stderr, - "function_arg( size=%d, words=%2d, nregs=%d, mode=%4s, named=%d", - words, cum->words, cum->nregs, GET_MODE_NAME (mode), named); - - if (ret) - fprintf (stderr, ", reg=%%e%s", reg_names[ REGNO(ret) ]); - else - fprintf (stderr, ", stack"); - - fprintf (stderr, " )\n"); - } - - return ret; -} - -/* For an arg passed partly in registers and partly in memory, - this is the number of registers used. - For args passed entirely in registers or entirely in memory, zero. */ - -int -function_arg_partial_nregs (cum, mode, type, named) - CUMULATIVE_ARGS *cum; /* current arg information */ - enum machine_mode mode; /* current arg mode */ - tree type; /* type of the argument or 0 if lib support */ - int named; /* != 0 for normal args, == 0 for ... args */ -{ - return 0; -} - - -/* Output an insn whose source is a 386 integer register. SRC is the - rtx for the register, and TEMPLATE is the op-code template. SRC may - be either SImode or DImode. - - The template will be output with operands[0] as SRC, and operands[1] - as a pointer to the top of the 386 stack. So a call from floatsidf2 - would look like this: - - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - - where %z0 corresponds to the caller's operands[1], and is used to - emit the proper size suffix. - - ??? Extend this to handle HImode - a 387 can load and store HImode - values directly. */ - -void -output_op_from_reg (src, template) - rtx src; - char *template; -{ - rtx xops[4]; - int size = GET_MODE_SIZE (GET_MODE (src)); - - xops[0] = src; - xops[1] = AT_SP (Pmode); - xops[2] = GEN_INT (size); - xops[3] = stack_pointer_rtx; - - if (size > UNITS_PER_WORD) - { - rtx high; - if (size > 2 * UNITS_PER_WORD) - { - high = gen_rtx (REG, SImode, REGNO (src) + 2); - output_asm_insn (AS1 (push%L0,%0), &high); - } - high = gen_rtx (REG, SImode, REGNO (src) + 1); - output_asm_insn (AS1 (push%L0,%0), &high); - } - output_asm_insn (AS1 (push%L0,%0), &src); - - output_asm_insn (template, xops); - - output_asm_insn (AS2 (add%L3,%2,%3), xops); -} - -/* Output an insn to pop an value from the 387 top-of-stack to 386 - register DEST. The 387 register stack is popped if DIES is true. If - the mode of DEST is an integer mode, a `fist' integer store is done, - otherwise a `fst' float store is done. */ - -void -output_to_reg (dest, dies) - rtx dest; - int dies; -{ - rtx xops[4]; - int size = GET_MODE_SIZE (GET_MODE (dest)); - - xops[0] = AT_SP (Pmode); - xops[1] = stack_pointer_rtx; - xops[2] = GEN_INT (size); - xops[3] = dest; - - output_asm_insn (AS2 (sub%L1,%2,%1), xops); - - if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT) - { - if (dies) - output_asm_insn (AS1 (fistp%z3,%y0), xops); - else - output_asm_insn (AS1 (fist%z3,%y0), xops); - } - else if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_FLOAT) - { - if (dies) - output_asm_insn (AS1 (fstp%z3,%y0), xops); - else - { - if (GET_MODE (dest) == XFmode) - { - output_asm_insn (AS1 (fstp%z3,%y0), xops); - output_asm_insn (AS1 (fld%z3,%y0), xops); - } - else - output_asm_insn (AS1 (fst%z3,%y0), xops); - } - } - else - abort (); - - output_asm_insn (AS1 (pop%L0,%0), &dest); - - if (size > UNITS_PER_WORD) - { - dest = gen_rtx (REG, SImode, REGNO (dest) + 1); - output_asm_insn (AS1 (pop%L0,%0), &dest); - if (size > 2 * UNITS_PER_WORD) - { - dest = gen_rtx (REG, SImode, REGNO (dest) + 1); - output_asm_insn (AS1 (pop%L0,%0), &dest); - } - } -} - -char * -singlemove_string (operands) - rtx *operands; -{ - rtx x; - if (GET_CODE (operands[0]) == MEM - && GET_CODE (x = XEXP (operands[0], 0)) == PRE_DEC) - { - if (XEXP (x, 0) != stack_pointer_rtx) - abort (); - return "push%L1 %1"; - } - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - return output_move_const_single (operands); - } - else if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG) - return AS2 (mov%L0,%1,%0); - else if (CONSTANT_P (operands[1])) - return AS2 (mov%L0,%1,%0); - else - { - output_asm_insn ("push%L1 %1", operands); - return "pop%L0 %0"; - } -} - -/* Return a REG that occurs in ADDR with coefficient 1. - ADDR can be effectively incremented by incrementing REG. */ - -static rtx -find_addr_reg (addr) - rtx addr; -{ - while (GET_CODE (addr) == PLUS) - { - if (GET_CODE (XEXP (addr, 0)) == REG) - addr = XEXP (addr, 0); - else if (GET_CODE (XEXP (addr, 1)) == REG) - addr = XEXP (addr, 1); - else if (CONSTANT_P (XEXP (addr, 0))) - addr = XEXP (addr, 1); - else if (CONSTANT_P (XEXP (addr, 1))) - addr = XEXP (addr, 0); - else - abort (); - } - if (GET_CODE (addr) == REG) - return addr; - abort (); -} - - -/* Output an insn to add the constant N to the register X. */ - -static void -asm_add (n, x) - int n; - rtx x; -{ - rtx xops[2]; - xops[0] = x; - - if (n == -1) - output_asm_insn (AS1 (dec%L0,%0), xops); - else if (n == 1) - output_asm_insn (AS1 (inc%L0,%0), xops); - else if (n < 0) - { - xops[1] = GEN_INT (-n); - output_asm_insn (AS2 (sub%L0,%1,%0), xops); - } - else if (n > 0) - { - xops[1] = GEN_INT (n); - output_asm_insn (AS2 (add%L0,%1,%0), xops); - } -} - - -/* Output assembler code to perform a doubleword move insn - with operands OPERANDS. */ - -char * -output_move_double (operands) - rtx *operands; -{ - enum {REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1; - rtx latehalf[2]; - rtx middlehalf[2]; - rtx xops[2]; - rtx addreg0 = 0, addreg1 = 0; - int dest_overlapped_low = 0; - int size = GET_MODE_SIZE (GET_MODE (operands[0])); - - middlehalf[0] = 0; - middlehalf[1] = 0; - - /* First classify both operands. */ - - if (REG_P (operands[0])) - optype0 = REGOP; - else if (offsettable_memref_p (operands[0])) - optype0 = OFFSOP; - else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC) - optype0 = POPOP; - else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - optype0 = PUSHOP; - else if (GET_CODE (operands[0]) == MEM) - optype0 = MEMOP; - else - optype0 = RNDOP; - - if (REG_P (operands[1])) - optype1 = REGOP; - else if (CONSTANT_P (operands[1])) - optype1 = CNSTOP; - else if (offsettable_memref_p (operands[1])) - optype1 = OFFSOP; - else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC) - optype1 = POPOP; - else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) - optype1 = PUSHOP; - else if (GET_CODE (operands[1]) == MEM) - optype1 = MEMOP; - else - optype1 = RNDOP; - - /* Check for the cases that the operand constraints are not - supposed to allow to happen. Abort if we get one, - because generating code for these cases is painful. */ - - if (optype0 == RNDOP || optype1 == RNDOP) - abort (); - - /* If one operand is decrementing and one is incrementing - decrement the former register explicitly - and change that operand into ordinary indexing. */ - - if (optype0 == PUSHOP && optype1 == POPOP) - { - /* ??? Can this ever happen on i386? */ - operands[0] = XEXP (XEXP (operands[0], 0), 0); - asm_add (-size, operands[0]); - if (GET_MODE (operands[1]) == XFmode) - operands[0] = gen_rtx (MEM, XFmode, operands[0]); - else if (GET_MODE (operands[0]) == DFmode) - operands[0] = gen_rtx (MEM, DFmode, operands[0]); - else - operands[0] = gen_rtx (MEM, DImode, operands[0]); - optype0 = OFFSOP; - } - - if (optype0 == POPOP && optype1 == PUSHOP) - { - /* ??? Can this ever happen on i386? */ - operands[1] = XEXP (XEXP (operands[1], 0), 0); - asm_add (-size, operands[1]); - if (GET_MODE (operands[1]) == XFmode) - operands[1] = gen_rtx (MEM, XFmode, operands[1]); - else if (GET_MODE (operands[1]) == DFmode) - operands[1] = gen_rtx (MEM, DFmode, operands[1]); - else - operands[1] = gen_rtx (MEM, DImode, operands[1]); - optype1 = OFFSOP; - } - - /* If an operand is an unoffsettable memory ref, find a register - we can increment temporarily to make it refer to the second word. */ - - if (optype0 == MEMOP) - addreg0 = find_addr_reg (XEXP (operands[0], 0)); - - if (optype1 == MEMOP) - addreg1 = find_addr_reg (XEXP (operands[1], 0)); - - /* Ok, we can do one word at a time. - Normally we do the low-numbered word first, - but if either operand is autodecrementing then we - do the high-numbered word first. - - In either case, set up in LATEHALF the operands to use - for the high-numbered word and in some cases alter the - operands in OPERANDS to be suitable for the low-numbered word. */ - - if (size == 12) - { - if (optype0 == REGOP) - { - middlehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2); - } - else if (optype0 == OFFSOP) - { - middlehalf[0] = adj_offsettable_operand (operands[0], 4); - latehalf[0] = adj_offsettable_operand (operands[0], 8); - } - else - { - middlehalf[0] = operands[0]; - latehalf[0] = operands[0]; - } - - if (optype1 == REGOP) - { - middlehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); - } - else if (optype1 == OFFSOP) - { - middlehalf[1] = adj_offsettable_operand (operands[1], 4); - latehalf[1] = adj_offsettable_operand (operands[1], 8); - } - else if (optype1 == CNSTOP) - { - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - REAL_VALUE_TYPE r; long l[3]; - - REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); - REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l); - operands[1] = GEN_INT (l[0]); - middlehalf[1] = GEN_INT (l[1]); - latehalf[1] = GEN_INT (l[2]); - } - else if (CONSTANT_P (operands[1])) - /* No non-CONST_DOUBLE constant should ever appear here. */ - abort (); - } - else - { - middlehalf[1] = operands[1]; - latehalf[1] = operands[1]; - } - } - else /* size is not 12: */ - { - if (optype0 == REGOP) - latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - else if (optype0 == OFFSOP) - latehalf[0] = adj_offsettable_operand (operands[0], 4); - else - latehalf[0] = operands[0]; - - if (optype1 == REGOP) - latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - else if (optype1 == OFFSOP) - latehalf[1] = adj_offsettable_operand (operands[1], 4); - else if (optype1 == CNSTOP) - split_double (operands[1], &operands[1], &latehalf[1]); - else - latehalf[1] = operands[1]; - } - - /* If insn is effectively movd N (sp),-(sp) then we will do the - high word first. We should use the adjusted operand 1 - (which is N+4 (sp) or N+8 (sp)) - for the low word and middle word as well, - to compensate for the first decrement of sp. */ - if (optype0 == PUSHOP - && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM - && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1])) - middlehalf[1] = operands[1] = latehalf[1]; - - /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)), - if the upper part of reg N does not appear in the MEM, arrange to - emit the move late-half first. Otherwise, compute the MEM address - into the upper part of N and use that as a pointer to the memory - operand. */ - if (optype0 == REGOP - && (optype1 == OFFSOP || optype1 == MEMOP)) - { - if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)) - && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0))) - { - /* If both halves of dest are used in the src memory address, - compute the address into latehalf of dest. */ -compadr: - xops[0] = latehalf[0]; - xops[1] = XEXP (operands[1], 0); - output_asm_insn (AS2 (lea%L0,%a1,%0), xops); - if( GET_MODE (operands[1]) == XFmode ) - { -/* abort (); */ - operands[1] = gen_rtx (MEM, XFmode, latehalf[0]); - middlehalf[1] = adj_offsettable_operand (operands[1], size-8); - latehalf[1] = adj_offsettable_operand (operands[1], size-4); - } - else - { - operands[1] = gen_rtx (MEM, DImode, latehalf[0]); - latehalf[1] = adj_offsettable_operand (operands[1], size-4); - } - } - else if (size == 12 - && reg_mentioned_p (middlehalf[0], XEXP (operands[1], 0))) - { - /* Check for two regs used by both source and dest. */ - if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)) - || reg_mentioned_p (latehalf[0], XEXP (operands[1], 0))) - goto compadr; - - /* JRV says this can't happen: */ - if (addreg0 || addreg1) - abort(); - - /* Only the middle reg conflicts; simply put it last. */ - output_asm_insn (singlemove_string (operands), operands); - output_asm_insn (singlemove_string (latehalf), latehalf); - output_asm_insn (singlemove_string (middlehalf), middlehalf); - return ""; - } - else if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))) - /* If the low half of dest is mentioned in the source memory - address, the arrange to emit the move late half first. */ - dest_overlapped_low = 1; - } - - /* If one or both operands autodecrementing, - do the two words, high-numbered first. */ - - /* Likewise, the first move would clobber the source of the second one, - do them in the other order. This happens only for registers; - such overlap can't happen in memory unless the user explicitly - sets it up, and that is an undefined circumstance. */ - -/* - if (optype0 == PUSHOP || optype1 == PUSHOP - || (optype0 == REGOP && optype1 == REGOP - && REGNO (operands[0]) == REGNO (latehalf[1])) - || dest_overlapped_low) -*/ - if (optype0 == PUSHOP || optype1 == PUSHOP - || (optype0 == REGOP && optype1 == REGOP - && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1])) - || REGNO (operands[0]) == REGNO (latehalf[1]))) - || dest_overlapped_low) - { - /* Make any unoffsettable addresses point at high-numbered word. */ - if (addreg0) - asm_add (size-4, addreg0); - if (addreg1) - asm_add (size-4, addreg1); - - /* Do that word. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - - /* Undo the adds we just did. */ - if (addreg0) - asm_add (-4, addreg0); - if (addreg1) - asm_add (-4, addreg1); - - if (size == 12) - { - output_asm_insn (singlemove_string (middlehalf), middlehalf); - if (addreg0) - asm_add (-4, addreg0); - if (addreg1) - asm_add (-4, addreg1); - } - - /* Do low-numbered word. */ - return singlemove_string (operands); - } - - /* Normal case: do the two words, low-numbered first. */ - - output_asm_insn (singlemove_string (operands), operands); - - /* Do the middle one of the three words for long double */ - if (size == 12) - { - if (addreg0) - asm_add (4, addreg0); - if (addreg1) - asm_add (4, addreg1); - - output_asm_insn (singlemove_string (middlehalf), middlehalf); - } - - /* Make any unoffsettable addresses point at high-numbered word. */ - if (addreg0) - asm_add (4, addreg0); - if (addreg1) - asm_add (4, addreg1); - - /* Do that word. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - - /* Undo the adds we just did. */ - if (addreg0) - asm_add (4-size, addreg0); - if (addreg1) - asm_add (4-size, addreg1); - - return ""; -} - - -#define MAX_TMPS 2 /* max temporary registers used */ - -/* Output the appropriate code to move push memory on the stack */ - -char * -output_move_pushmem (operands, insn, length, tmp_start, n_operands) - rtx operands[]; - rtx insn; - int length; - int tmp_start; - int n_operands; -{ - - struct { - char *load; - char *push; - rtx xops[2]; - } tmp_info[MAX_TMPS]; - - rtx src = operands[1]; - int max_tmps = 0; - int offset = 0; - int stack_p = reg_overlap_mentioned_p (stack_pointer_rtx, src); - int stack_offset = 0; - int i, num_tmps; - rtx xops[1]; - - if (!offsettable_memref_p (src)) - fatal_insn ("Source is not offsettable", insn); - - if ((length & 3) != 0) - fatal_insn ("Pushing non-word aligned size", insn); - - /* Figure out which temporary registers we have available */ - for (i = tmp_start; i < n_operands; i++) - { - if (GET_CODE (operands[i]) == REG) - { - if (reg_overlap_mentioned_p (operands[i], src)) - continue; - - tmp_info[ max_tmps++ ].xops[1] = operands[i]; - if (max_tmps == MAX_TMPS) - break; - } - } - - if (max_tmps == 0) - for (offset = length - 4; offset >= 0; offset -= 4) - { - xops[0] = adj_offsettable_operand (src, offset + stack_offset); - output_asm_insn (AS1(push%L0,%0), xops); - if (stack_p) - stack_offset += 4; - } - - else - for (offset = length - 4; offset >= 0; ) - { - for (num_tmps = 0; num_tmps < max_tmps && offset >= 0; num_tmps++) - { - tmp_info[num_tmps].load = AS2(mov%L0,%0,%1); - tmp_info[num_tmps].push = AS1(push%L0,%1); - tmp_info[num_tmps].xops[0] = adj_offsettable_operand (src, offset + stack_offset); - offset -= 4; - } - - for (i = 0; i < num_tmps; i++) - output_asm_insn (tmp_info[i].load, tmp_info[i].xops); - - for (i = 0; i < num_tmps; i++) - output_asm_insn (tmp_info[i].push, tmp_info[i].xops); - - if (stack_p) - stack_offset += 4*num_tmps; - } - - return ""; -} - - - -/* Output the appropriate code to move data between two memory locations */ - -char * -output_move_memory (operands, insn, length, tmp_start, n_operands) - rtx operands[]; - rtx insn; - int length; - int tmp_start; - int n_operands; -{ - struct { - char *load; - char *store; - rtx xops[3]; - } tmp_info[MAX_TMPS]; - - rtx dest = operands[0]; - rtx src = operands[1]; - rtx qi_tmp = NULL_RTX; - int max_tmps = 0; - int offset = 0; - int i, num_tmps; - rtx xops[3]; - - if (GET_CODE (dest) == MEM - && GET_CODE (XEXP (dest, 0)) == PRE_INC - && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx) - return output_move_pushmem (operands, insn, length, tmp_start, n_operands); - - if (!offsettable_memref_p (src)) - fatal_insn ("Source is not offsettable", insn); - - if (!offsettable_memref_p (dest)) - fatal_insn ("Destination is not offsettable", insn); - - /* Figure out which temporary registers we have available */ - for (i = tmp_start; i < n_operands; i++) - { - if (GET_CODE (operands[i]) == REG) - { - if ((length & 1) != 0 && !qi_tmp && QI_REG_P (operands[i])) - qi_tmp = operands[i]; - - if (reg_overlap_mentioned_p (operands[i], dest)) - fatal_insn ("Temporary register overlaps the destination", insn); - - if (reg_overlap_mentioned_p (operands[i], src)) - fatal_insn ("Temporary register overlaps the source", insn); - - tmp_info[ max_tmps++ ].xops[2] = operands[i]; - if (max_tmps == MAX_TMPS) - break; - } - } - - if (max_tmps == 0) - fatal_insn ("No scratch registers were found to do memory->memory moves", insn); - - if ((length & 1) != 0) - { - if (!qi_tmp) - fatal_insn ("No byte register found when moving odd # of bytes.", insn); - } - - while (length > 1) - { - for (num_tmps = 0; num_tmps < max_tmps; num_tmps++) - { - if (length >= 4) - { - tmp_info[num_tmps].load = AS2(mov%L0,%1,%2); - tmp_info[num_tmps].store = AS2(mov%L0,%2,%0); - tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset); - tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset); - offset += 4; - length -= 4; - } - else if (length >= 2) - { - tmp_info[num_tmps].load = AS2(mov%W0,%1,%2); - tmp_info[num_tmps].store = AS2(mov%W0,%2,%0); - tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset); - tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset); - offset += 2; - length -= 2; - } - else - break; - } - - for (i = 0; i < num_tmps; i++) - output_asm_insn (tmp_info[i].load, tmp_info[i].xops); - - for (i = 0; i < num_tmps; i++) - output_asm_insn (tmp_info[i].store, tmp_info[i].xops); - } - - if (length == 1) - { - xops[0] = adj_offsettable_operand (dest, offset); - xops[1] = adj_offsettable_operand (src, offset); - xops[2] = qi_tmp; - output_asm_insn (AS2(mov%B0,%1,%2), xops); - output_asm_insn (AS2(mov%B0,%2,%0), xops); - } - - return ""; -} - - -int -standard_80387_constant_p (x) - rtx x; -{ -#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC) - REAL_VALUE_TYPE d; - jmp_buf handler; - int is0, is1; - - if (setjmp (handler)) - return 0; - - set_float_handler (handler); - REAL_VALUE_FROM_CONST_DOUBLE (d, x); - is0 = REAL_VALUES_EQUAL (d, dconst0); - is1 = REAL_VALUES_EQUAL (d, dconst1); - set_float_handler (NULL_PTR); - - if (is0) - return 1; - - if (is1) - return 2; - - /* Note that on the 80387, other constants, such as pi, - are much slower to load as standard constants - than to load from doubles in memory! */ -#endif - - return 0; -} - -char * -output_move_const_single (operands) - rtx *operands; -{ - if (FP_REG_P (operands[0])) - { - int conval = standard_80387_constant_p (operands[1]); - - if (conval == 1) - return "fldz"; - - if (conval == 2) - return "fld1"; - } - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - REAL_VALUE_TYPE r; long l; - - if (GET_MODE (operands[1]) == XFmode) - abort (); - - REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); - REAL_VALUE_TO_TARGET_SINGLE (r, l); - operands[1] = GEN_INT (l); - } - return singlemove_string (operands); -} - -/* Returns 1 if OP is either a symbol reference or a sum of a symbol - reference and a constant. */ - -int -symbolic_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - switch (GET_CODE (op)) - { - case SYMBOL_REF: - case LABEL_REF: - return 1; - case CONST: - op = XEXP (op, 0); - return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF - || GET_CODE (XEXP (op, 0)) == LABEL_REF) - && GET_CODE (XEXP (op, 1)) == CONST_INT); - default: - return 0; - } -} - -/* Test for a valid operand for a call instruction. - Don't allow the arg pointer register or virtual regs - since they may change into reg + const, which the patterns - can't handle yet. */ - -int -call_insn_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) == MEM - && ((CONSTANT_ADDRESS_P (XEXP (op, 0)) - /* This makes a difference for PIC. */ - && general_operand (XEXP (op, 0), Pmode)) - || (GET_CODE (XEXP (op, 0)) == REG - && XEXP (op, 0) != arg_pointer_rtx - && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER - && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER)))) - return 1; - return 0; -} - -/* Like call_insn_operand but allow (mem (symbol_ref ...)) - even if pic. */ - -int -expander_call_insn_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) == MEM - && (CONSTANT_ADDRESS_P (XEXP (op, 0)) - || (GET_CODE (XEXP (op, 0)) == REG - && XEXP (op, 0) != arg_pointer_rtx - && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER - && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER)))) - return 1; - return 0; -} - -/* Return 1 if OP is a comparison operator that can use the condition code - generated by an arithmetic operation. */ - -int -arithmetic_comparison_operator (op, mode) - register rtx op; - enum machine_mode mode; -{ - enum rtx_code code; - - if (mode != VOIDmode && mode != GET_MODE (op)) - return 0; - code = GET_CODE (op); - if (GET_RTX_CLASS (code) != '<') - return 0; - - return (code != GT && code != LE); -} - -/* Returns 1 if OP contains a symbol reference */ - -int -symbolic_reference_mentioned_p (op) - rtx op; -{ - register char *fmt; - register int i; - - if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF) - return 1; - - fmt = GET_RTX_FORMAT (GET_CODE (op)); - for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--) - { - if (fmt[i] == 'E') - { - register int j; - - for (j = XVECLEN (op, i) - 1; j >= 0; j--) - if (symbolic_reference_mentioned_p (XVECEXP (op, i, j))) - return 1; - } - else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i))) - return 1; - } - - return 0; -} - -/* This function generates the assembly code for function entry. - FILE is an stdio stream to output the code to. - SIZE is an int: how many units of temporary storage to allocate. */ - -void -function_prologue (file, size) - FILE *file; - int size; -{ - register int regno; - int limit; - rtx xops[4]; - int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table - || current_function_uses_const_pool); - - xops[0] = stack_pointer_rtx; - xops[1] = frame_pointer_rtx; - xops[2] = GEN_INT (size); - if (frame_pointer_needed) - { - output_asm_insn ("push%L1 %1", xops); - output_asm_insn (AS2 (mov%L0,%0,%1), xops); - } - - if (size) - output_asm_insn (AS2 (sub%L0,%2,%0), xops); - - /* Note If use enter it is NOT reversed args. - This one is not reversed from intel!! - I think enter is slower. Also sdb doesn't like it. - But if you want it the code is: - { - xops[3] = const0_rtx; - output_asm_insn ("enter %2,%3", xops); - } - */ - limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM); - for (regno = limit - 1; regno >= 0; regno--) - if ((regs_ever_live[regno] && ! call_used_regs[regno]) - || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used)) - { - xops[0] = gen_rtx (REG, SImode, regno); - output_asm_insn ("push%L0 %0", xops); - } - - if (pic_reg_used) - { - xops[0] = pic_offset_table_rtx; - xops[1] = (rtx) gen_label_rtx (); - - output_asm_insn (AS1 (call,%P1), xops); - ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1])); - output_asm_insn (AS1 (pop%L0,%0), xops); - output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops); - } -} - -/* Return 1 if it is appropriate to emit `ret' instructions in the - body of a function. Do this only if the epilogue is simple, needing a - couple of insns. Prior to reloading, we can't tell how many registers - must be saved, so return 0 then. - - If NON_SAVING_SETJMP is defined and true, then it is not possible - for the epilogue to be simple, so return 0. This is a special case - since NON_SAVING_SETJMP will not cause regs_ever_live to change until - final, but jump_optimize may need to know sooner if a `return' is OK. */ - -int -simple_386_epilogue () -{ - int regno; - int nregs = 0; - int reglimit = (frame_pointer_needed - ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM); - int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table - || current_function_uses_const_pool); - -#ifdef NON_SAVING_SETJMP - if (NON_SAVING_SETJMP && current_function_calls_setjmp) - return 0; -#endif - - if (! reload_completed) - return 0; - - for (regno = reglimit - 1; regno >= 0; regno--) - if ((regs_ever_live[regno] && ! call_used_regs[regno]) - || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used)) - nregs++; - - return nregs == 0 || ! frame_pointer_needed; -} - - -/* This function generates the assembly code for function exit. - FILE is an stdio stream to output the code to. - SIZE is an int: how many units of temporary storage to deallocate. */ - -void -function_epilogue (file, size) - FILE *file; - int size; -{ - register int regno; - register int nregs, limit; - int offset; - rtx xops[3]; - int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table - || current_function_uses_const_pool); - - /* Compute the number of registers to pop */ - - limit = (frame_pointer_needed - ? FRAME_POINTER_REGNUM - : STACK_POINTER_REGNUM); - - nregs = 0; - - for (regno = limit - 1; regno >= 0; regno--) - if ((regs_ever_live[regno] && ! call_used_regs[regno]) - || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used)) - nregs++; - - /* sp is often unreliable so we must go off the frame pointer, - */ - - /* In reality, we may not care if sp is unreliable, because we can - restore the register relative to the frame pointer. In theory, - since each move is the same speed as a pop, and we don't need the - leal, this is faster. For now restore multiple registers the old - way. */ - - offset = -size - (nregs * UNITS_PER_WORD); - - xops[2] = stack_pointer_rtx; - - if (nregs > 1 || ! frame_pointer_needed) - { - if (frame_pointer_needed) - { - xops[0] = adj_offsettable_operand (AT_BP (Pmode), offset); - output_asm_insn (AS2 (lea%L2,%0,%2), xops); - } - - for (regno = 0; regno < limit; regno++) - if ((regs_ever_live[regno] && ! call_used_regs[regno]) - || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used)) - { - xops[0] = gen_rtx (REG, SImode, regno); - output_asm_insn ("pop%L0 %0", xops); - } - } - else - for (regno = 0; regno < limit; regno++) - if ((regs_ever_live[regno] && ! call_used_regs[regno]) - || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used)) - { - xops[0] = gen_rtx (REG, SImode, regno); - xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset); - output_asm_insn (AS2 (mov%L0,%1,%0), xops); - offset += 4; - } - - if (frame_pointer_needed) - { - /* On i486, mov & pop is faster than "leave". */ - - if (!TARGET_386) - { - xops[0] = frame_pointer_rtx; - output_asm_insn (AS2 (mov%L2,%0,%2), xops); - output_asm_insn ("pop%L0 %0", xops); - } - else - output_asm_insn ("leave", xops); - } - else if (size) - { - /* If there is no frame pointer, we must still release the frame. */ - - xops[0] = GEN_INT (size); - output_asm_insn (AS2 (add%L2,%0,%2), xops); - } - - if (current_function_pops_args && current_function_args_size) - { - xops[1] = GEN_INT (current_function_pops_args); - - /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If - asked to pop more, pop return address, do explicit add, and jump - indirectly to the caller. */ - - if (current_function_pops_args >= 32768) - { - /* ??? Which register to use here? */ - xops[0] = gen_rtx (REG, SImode, 2); - output_asm_insn ("pop%L0 %0", xops); - output_asm_insn (AS2 (add%L2,%1,%2), xops); - output_asm_insn ("jmp %*%0", xops); - } - else - output_asm_insn ("ret %1", xops); - } - else - output_asm_insn ("ret", xops); -} - - -/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression - that is a valid memory address for an instruction. - The MODE argument is the machine mode for the MEM expression - that wants to use this address. - - On x86, legitimate addresses are: - base movl (base),reg - displacement movl disp,reg - base + displacement movl disp(base),reg - index + base movl (base,index),reg - (index + base) + displacement movl disp(base,index),reg - index*scale movl (,index,scale),reg - index*scale + disp movl disp(,index,scale),reg - index*scale + base movl (base,index,scale),reg - (index*scale + base) + disp movl disp(base,index,scale),reg - - In each case, scale can be 1, 2, 4, 8. */ - -/* This is exactly the same as print_operand_addr, except that - it recognizes addresses instead of printing them. - - It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should - convert common non-canonical forms to canonical form so that they will - be recognized. */ - -#define ADDR_INVALID(msg,insn) \ -do { \ - if (TARGET_DEBUG_ADDR) \ - { \ - fprintf (stderr, msg); \ - debug_rtx (insn); \ - } \ -} while (0) - -int -legitimate_address_p (mode, addr, strict) - enum machine_mode mode; - register rtx addr; - int strict; -{ - rtx base = NULL_RTX; - rtx indx = NULL_RTX; - rtx scale = NULL_RTX; - rtx disp = NULL_RTX; - - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, - "\n==========\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n", - GET_MODE_NAME (mode), strict); - - debug_rtx (addr); - } - - if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG) - base = addr; /* base reg */ - - else if (GET_CODE (addr) == PLUS) - { - rtx op0 = XEXP (addr, 0); - rtx op1 = XEXP (addr, 1); - enum rtx_code code0 = GET_CODE (op0); - enum rtx_code code1 = GET_CODE (op1); - - if (code0 == REG || code0 == SUBREG) - { - if (code1 == REG || code1 == SUBREG) - { - indx = op0; /* index + base */ - base = op1; - } - - else - { - base = op0; /* base + displacement */ - disp = op1; - } - } - - else if (code0 == MULT) - { - indx = XEXP (op0, 0); - scale = XEXP (op0, 1); - - if (code1 == REG || code1 == SUBREG) - base = op1; /* index*scale + base */ - - else - disp = op1; /* index*scale + disp */ - } - - else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT) - { - indx = XEXP (XEXP (op0, 0), 0); /* index*scale + base + disp */ - scale = XEXP (XEXP (op0, 0), 1); - base = XEXP (op0, 1); - disp = op1; - } - - else if (code0 == PLUS) - { - indx = XEXP (op0, 0); /* index + base + disp */ - base = XEXP (op0, 1); - disp = op1; - } - - else - { - ADDR_INVALID ("PLUS subcode is not valid.\n", op0); - return FALSE; - } - } - - else if (GET_CODE (addr) == MULT) - { - indx = XEXP (addr, 0); /* index*scale */ - scale = XEXP (addr, 1); - } - - else - disp = addr; /* displacement */ - - /* Allow arg pointer and stack pointer as index if there is not scaling */ - if (base && indx && !scale - && (indx == arg_pointer_rtx || indx == stack_pointer_rtx)) - { - rtx tmp = base; - base = indx; - indx = tmp; - } - - /* Validate base register */ - /* Don't allow SUBREG's here, it can lead to spill failures when the base - is one word out of a two word structure, which is represented internally - as a DImode int. */ - if (base) - { - if (GET_CODE (base) != REG) - { - ADDR_INVALID ("Base is not a register.\n", base); - return FALSE; - } - - if ((strict && !REG_OK_FOR_BASE_STRICT_P (base)) - || (!strict && !REG_OK_FOR_BASE_NONSTRICT_P (base))) - { - ADDR_INVALID ("Base is not valid.\n", base); - return FALSE; - } - } - - /* Validate index register */ - /* Don't allow SUBREG's here, it can lead to spill failures when the index - is one word out of a two word structure, which is represented internally - as a DImode int. */ - if (indx) - { - if (GET_CODE (indx) != REG) - { - ADDR_INVALID ("Index is not a register.\n", indx); - return FALSE; - } - - if ((strict && !REG_OK_FOR_INDEX_STRICT_P (indx)) - || (!strict && !REG_OK_FOR_INDEX_NONSTRICT_P (indx))) - { - ADDR_INVALID ("Index is not valid.\n", indx); - return FALSE; - } - } - else if (scale) - abort (); /* scale w/o index invalid */ - - /* Validate scale factor */ - if (scale) - { - HOST_WIDE_INT value; - - if (GET_CODE (scale) != CONST_INT) - { - ADDR_INVALID ("Scale is not valid.\n", scale); - return FALSE; - } - - value = INTVAL (scale); - if (value != 1 && value != 2 && value != 4 && value != 8) - { - ADDR_INVALID ("Scale is not a good multiplier.\n", scale); - return FALSE; - } - } - - /* Validate displacement */ - if (disp) - { - if (!CONSTANT_ADDRESS_P (disp)) - { - ADDR_INVALID ("Displacement is not valid.\n", disp); - return FALSE; - } - - if (GET_CODE (disp) == CONST_DOUBLE) - { - ADDR_INVALID ("Displacement is a const_double.\n", disp); - return FALSE; - } - - if (flag_pic && SYMBOLIC_CONST (disp) && base != pic_offset_table_rtx - && (indx != pic_offset_table_rtx || scale != NULL_RTX)) - { - ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp); - return FALSE; - } - - if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp) - && (base != NULL_RTX || indx != NULL_RTX)) - { - ADDR_INVALID ("Displacement is an invalid half-pic reference.\n", disp); - return FALSE; - } - } - - if (TARGET_DEBUG_ADDR) - fprintf (stderr, "Address is valid.\n"); - - /* Everything looks valid, return true */ - return TRUE; -} - - -/* Return a legitimate reference for ORIG (an address) using the - register REG. If REG is 0, a new pseudo is generated. - - There are three types of references that must be handled: - - 1. Global data references must load the address from the GOT, via - the PIC reg. An insn is emitted to do this load, and the reg is - returned. - - 2. Static data references must compute the address as an offset - from the GOT, whose base is in the PIC reg. An insn is emitted to - compute the address into a reg, and the reg is returned. Static - data objects have SYMBOL_REF_FLAG set to differentiate them from - global data objects. - - 3. Constant pool addresses must be handled special. They are - considered legitimate addresses, but only if not used with regs. - When printed, the output routines know to print the reference with the - PIC reg, even though the PIC reg doesn't appear in the RTL. - - GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC - reg also appears in the address (except for constant pool references, - noted above). - - "switch" statements also require special handling when generating - PIC code. See comments by the `casesi' insn in i386.md for details. */ - -rtx -legitimize_pic_address (orig, reg) - rtx orig; - rtx reg; -{ - rtx addr = orig; - rtx new = orig; - - if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF) - { - if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr)) - reg = new = orig; - else - { - if (reg == 0) - reg = gen_reg_rtx (Pmode); - - if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr)) - || GET_CODE (addr) == LABEL_REF) - new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig); - else - new = gen_rtx (MEM, Pmode, - gen_rtx (PLUS, Pmode, - pic_offset_table_rtx, orig)); - - emit_move_insn (reg, new); - } - current_function_uses_pic_offset_table = 1; - return reg; - } - else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS) - { - rtx base; - - if (GET_CODE (addr) == CONST) - { - addr = XEXP (addr, 0); - if (GET_CODE (addr) != PLUS) - abort (); - } - - if (XEXP (addr, 0) == pic_offset_table_rtx) - return orig; - - if (reg == 0) - reg = gen_reg_rtx (Pmode); - - base = legitimize_pic_address (XEXP (addr, 0), reg); - addr = legitimize_pic_address (XEXP (addr, 1), - base == reg ? NULL_RTX : reg); - - if (GET_CODE (addr) == CONST_INT) - return plus_constant (base, INTVAL (addr)); - - if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1))) - { - base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0)); - addr = XEXP (addr, 1); - } - return gen_rtx (PLUS, Pmode, base, addr); - } - return new; -} - - -/* Emit insns to move operands[1] into operands[0]. */ - -void -emit_pic_move (operands, mode) - rtx *operands; - enum machine_mode mode; -{ - rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode); - - if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1])) - operands[1] = (rtx) force_reg (SImode, operands[1]); - else - operands[1] = legitimize_pic_address (operands[1], temp); -} - - -/* Try machine-dependent ways of modifying an illegitimate address - to be legitimate. If we find one, return the new, valid address. - This macro is used in only one place: `memory_address' in explow.c. - - OLDX is the address as it was before break_out_memory_refs was called. - In some cases it is useful to look at this to decide what needs to be done. - - MODE and WIN are passed so that this macro can use - GO_IF_LEGITIMATE_ADDRESS. - - It is always safe for this macro to do nothing. It exists to recognize - opportunities to optimize the output. - - For the 80386, we handle X+REG by loading X into a register R and - using R+REG. R will go in a general reg and indexing will be used. - However, if REG is a broken-out memory address or multiplication, - nothing needs to be done because REG can certainly go in a general reg. - - When -fpic is used, special handling is needed for symbolic references. - See comments by legitimize_pic_address in i386.c for details. */ - -rtx -legitimize_address (x, oldx, mode) - register rtx x; - register rtx oldx; - enum machine_mode mode; -{ - int changed = 0; - unsigned log; - - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n", GET_MODE_NAME (mode)); - debug_rtx (x); - } - - if (flag_pic && SYMBOLIC_CONST (x)) - return legitimize_pic_address (x, 0); - - /* Canonicalize shifts by 0, 1, 2, 3 into multiply */ - if (GET_CODE (x) == ASHIFT - && GET_CODE (XEXP (x, 1)) == CONST_INT - && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4) - { - changed = 1; - x = gen_rtx (MULT, Pmode, - force_reg (Pmode, XEXP (x, 0)), - GEN_INT (1 << log)); - } - - if (GET_CODE (x) == PLUS) - { - /* Canonicalize shifts by 0, 1, 2, 3 into multiply */ - if (GET_CODE (XEXP (x, 0)) == ASHIFT - && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT - && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4) - { - changed = 1; - XEXP (x, 0) = gen_rtx (MULT, Pmode, - force_reg (Pmode, XEXP (XEXP (x, 0), 0)), - GEN_INT (1 << log)); - } - - if (GET_CODE (XEXP (x, 1)) == ASHIFT - && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT - && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4) - { - changed = 1; - XEXP (x, 1) = gen_rtx (MULT, Pmode, - force_reg (Pmode, XEXP (XEXP (x, 1), 0)), - GEN_INT (1 << log)); - } - - /* Put multiply first if it isn't already */ - if (GET_CODE (XEXP (x, 1)) == MULT) - { - rtx tmp = XEXP (x, 0); - XEXP (x, 0) = XEXP (x, 1); - XEXP (x, 1) = tmp; - changed = 1; - } - - /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const))) - into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be - created by virtual register instantiation, register elimination, and - similar optimizations. */ - if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS) - { - changed = 1; - x = gen_rtx (PLUS, Pmode, - gen_rtx (PLUS, Pmode, XEXP (x, 0), XEXP (XEXP (x, 1), 0)), - XEXP (XEXP (x, 1), 1)); - } - - /* Canonicalize (plus (plus (mult (reg) (const)) (plus (reg) (const))) const) - into (plus (plus (mult (reg) (const)) (reg)) (const)). */ - else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT - && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS - && CONSTANT_P (XEXP (x, 1))) - { - rtx constant, other; - - if (GET_CODE (XEXP (x, 1)) == CONST_INT) - { - constant = XEXP (x, 1); - other = XEXP (XEXP (XEXP (x, 0), 1), 1); - } - else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT) - { - constant = XEXP (XEXP (XEXP (x, 0), 1), 1); - other = XEXP (x, 1); - } - else - constant = 0; - - if (constant) - { - changed = 1; - x = gen_rtx (PLUS, Pmode, - gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0), - XEXP (XEXP (XEXP (x, 0), 1), 0)), - plus_constant (other, INTVAL (constant))); - } - } - - if (changed && legitimate_address_p (mode, x, FALSE)) - return x; - - if (GET_CODE (XEXP (x, 0)) == MULT) - { - changed = 1; - XEXP (x, 0) = force_operand (XEXP (x, 0), 0); - } - - if (GET_CODE (XEXP (x, 1)) == MULT) - { - changed = 1; - XEXP (x, 1) = force_operand (XEXP (x, 1), 0); - } - - if (changed - && GET_CODE (XEXP (x, 1)) == REG - && GET_CODE (XEXP (x, 0)) == REG) - return x; - - if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1))) - { - changed = 1; - x = legitimize_pic_address (x, 0); - } - - if (changed && legitimate_address_p (mode, x, FALSE)) - return x; - - if (GET_CODE (XEXP (x, 0)) == REG) - { - register rtx temp = gen_reg_rtx (Pmode); - register rtx val = force_operand (XEXP (x, 1), temp); - if (val != temp) - emit_move_insn (temp, val); - - XEXP (x, 1) = temp; - return x; - } - - else if (GET_CODE (XEXP (x, 1)) == REG) - { - register rtx temp = gen_reg_rtx (Pmode); - register rtx val = force_operand (XEXP (x, 0), temp); - if (val != temp) - emit_move_insn (temp, val); - - XEXP (x, 0) = temp; - return x; - } - } - - return x; -} - - -/* Print an integer constant expression in assembler syntax. Addition - and subtraction are the only arithmetic that may appear in these - expressions. FILE is the stdio stream to write to, X is the rtx, and - CODE is the operand print code from the output string. */ - -static void -output_pic_addr_const (file, x, code) - FILE *file; - rtx x; - int code; -{ - char buf[256]; - - switch (GET_CODE (x)) - { - case PC: - if (flag_pic) - putc ('.', file); - else - abort (); - break; - - case SYMBOL_REF: - case LABEL_REF: - if (GET_CODE (x) == SYMBOL_REF) - assemble_name (file, XSTR (x, 0)); - else - { - ASM_GENERATE_INTERNAL_LABEL (buf, "L", - CODE_LABEL_NUMBER (XEXP (x, 0))); - assemble_name (asm_out_file, buf); - } - - if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x)) - fprintf (file, "@GOTOFF(%%ebx)"); - else if (code == 'P') - fprintf (file, "@PLT"); - else if (GET_CODE (x) == LABEL_REF) - fprintf (file, "@GOTOFF"); - else if (! SYMBOL_REF_FLAG (x)) - fprintf (file, "@GOT"); - else - fprintf (file, "@GOTOFF"); - - break; - - case CODE_LABEL: - ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x)); - assemble_name (asm_out_file, buf); - break; - - case CONST_INT: - fprintf (file, "%d", INTVAL (x)); - break; - - case CONST: - /* This used to output parentheses around the expression, - but that does not work on the 386 (either ATT or BSD assembler). */ - output_pic_addr_const (file, XEXP (x, 0), code); - break; - - case CONST_DOUBLE: - if (GET_MODE (x) == VOIDmode) - { - /* We can use %d if the number is <32 bits and positive. */ - if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0) - fprintf (file, "0x%x%08x", - CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x)); - else - fprintf (file, "%d", CONST_DOUBLE_LOW (x)); - } - else - /* We can't handle floating point constants; - PRINT_OPERAND must handle them. */ - output_operand_lossage ("floating constant misused"); - break; - - case PLUS: - /* Some assemblers need integer constants to appear last (eg masm). */ - if (GET_CODE (XEXP (x, 0)) == CONST_INT) - { - output_pic_addr_const (file, XEXP (x, 1), code); - if (INTVAL (XEXP (x, 0)) >= 0) - fprintf (file, "+"); - output_pic_addr_const (file, XEXP (x, 0), code); - } - else - { - output_pic_addr_const (file, XEXP (x, 0), code); - if (INTVAL (XEXP (x, 1)) >= 0) - fprintf (file, "+"); - output_pic_addr_const (file, XEXP (x, 1), code); - } - break; - - case MINUS: - output_pic_addr_const (file, XEXP (x, 0), code); - fprintf (file, "-"); - output_pic_addr_const (file, XEXP (x, 1), code); - break; - - default: - output_operand_lossage ("invalid expression as operand"); - } -} - -/* Meaning of CODE: - f -- float insn (print a CONST_DOUBLE as a float rather than in hex). - D,L,W,B,Q,S -- print the opcode suffix for specified size of operand. - R -- print the prefix for register names. - z -- print the opcode suffix for the size of the current operand. - * -- print a star (in certain assembler syntax) - w -- print the operand as if it's a "word" (HImode) even if it isn't. - c -- don't print special prefixes before constant operands. - J -- print the appropriate jump operand. -*/ - -void -print_operand (file, x, code) - FILE *file; - rtx x; - int code; -{ - if (code) - { - switch (code) - { - case '*': - if (USE_STAR) - putc ('*', file); - return; - - case 'L': - PUT_OP_SIZE (code, 'l', file); - return; - - case 'W': - PUT_OP_SIZE (code, 'w', file); - return; - - case 'B': - PUT_OP_SIZE (code, 'b', file); - return; - - case 'Q': - PUT_OP_SIZE (code, 'l', file); - return; - - case 'S': - PUT_OP_SIZE (code, 's', file); - return; - - case 'T': - PUT_OP_SIZE (code, 't', file); - return; - - case 'z': - /* 387 opcodes don't get size suffixes if the operands are - registers. */ - - if (STACK_REG_P (x)) - return; - - /* this is the size of op from size of operand */ - switch (GET_MODE_SIZE (GET_MODE (x))) - { - case 1: - PUT_OP_SIZE ('B', 'b', file); - return; - - case 2: - PUT_OP_SIZE ('W', 'w', file); - return; - - case 4: - if (GET_MODE (x) == SFmode) - { - PUT_OP_SIZE ('S', 's', file); - return; - } - else - PUT_OP_SIZE ('L', 'l', file); - return; - - case 12: - PUT_OP_SIZE ('T', 't', file); - return; - - case 8: - if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT) - { -#ifdef GAS_MNEMONICS - PUT_OP_SIZE ('Q', 'q', file); - return; -#else - PUT_OP_SIZE ('Q', 'l', file); /* Fall through */ -#endif - } - - PUT_OP_SIZE ('Q', 'l', file); - return; - } - - case 'b': - case 'w': - case 'k': - case 'h': - case 'y': - case 'P': - break; - - case 'J': - switch (GET_CODE (x)) - { - /* These conditions are appropriate for testing the result - of an arithmetic operation, not for a compare operation. - Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume - CC_Z_IN_NOT_C false and not floating point. */ - case NE: fputs ("jne", file); return; - case EQ: fputs ("je", file); return; - case GE: fputs ("jns", file); return; - case LT: fputs ("js", file); return; - case GEU: fputs ("jmp", file); return; - case GTU: fputs ("jne", file); return; - case LEU: fputs ("je", file); return; - case LTU: fputs ("#branch never", file); return; - - /* no matching branches for GT nor LE */ - } - abort (); - - default: - { - char str[50]; - - sprintf (str, "invalid operand code `%c'", code); - output_operand_lossage (str); - } - } - } - if (GET_CODE (x) == REG) - { - PRINT_REG (x, code, file); - } - else if (GET_CODE (x) == MEM) - { - PRINT_PTR (x, file); - if (CONSTANT_ADDRESS_P (XEXP (x, 0))) - { - if (flag_pic) - output_pic_addr_const (file, XEXP (x, 0), code); - else - output_addr_const (file, XEXP (x, 0)); - } - else - output_address (XEXP (x, 0)); - } - else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode) - { - REAL_VALUE_TYPE r; long l; - REAL_VALUE_FROM_CONST_DOUBLE (r, x); - REAL_VALUE_TO_TARGET_SINGLE (r, l); - PRINT_IMMED_PREFIX (file); - fprintf (file, "0x%x", l); - } - /* These float cases don't actually occur as immediate operands. */ - else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode) - { - REAL_VALUE_TYPE r; char dstr[30]; - REAL_VALUE_FROM_CONST_DOUBLE (r, x); - REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr); - fprintf (file, "%s", dstr); - } - else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode) - { - REAL_VALUE_TYPE r; char dstr[30]; - REAL_VALUE_FROM_CONST_DOUBLE (r, x); - REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr); - fprintf (file, "%s", dstr); - } - else - { - if (code != 'P') - { - if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE) - PRINT_IMMED_PREFIX (file); - else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF - || GET_CODE (x) == LABEL_REF) - PRINT_OFFSET_PREFIX (file); - } - if (flag_pic) - output_pic_addr_const (file, x, code); - else - output_addr_const (file, x); - } -} - -/* Print a memory operand whose address is ADDR. */ - -void -print_operand_address (file, addr) - FILE *file; - register rtx addr; -{ - register rtx reg1, reg2, breg, ireg; - rtx offset; - - switch (GET_CODE (addr)) - { - case REG: - ADDR_BEG (file); - fprintf (file, "%se", RP); - fputs (hi_reg_name[REGNO (addr)], file); - ADDR_END (file); - break; - - case PLUS: - reg1 = 0; - reg2 = 0; - ireg = 0; - breg = 0; - offset = 0; - if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) - { - offset = XEXP (addr, 0); - addr = XEXP (addr, 1); - } - else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) - { - offset = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - if (GET_CODE (addr) != PLUS) ; - else if (GET_CODE (XEXP (addr, 0)) == MULT) - { - reg1 = XEXP (addr, 0); - addr = XEXP (addr, 1); - } - else if (GET_CODE (XEXP (addr, 1)) == MULT) - { - reg1 = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - else if (GET_CODE (XEXP (addr, 0)) == REG) - { - reg1 = XEXP (addr, 0); - addr = XEXP (addr, 1); - } - else if (GET_CODE (XEXP (addr, 1)) == REG) - { - reg1 = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT) - { - if (reg1 == 0) reg1 = addr; - else reg2 = addr; - addr = 0; - } - if (offset != 0) - { - if (addr != 0) abort (); - addr = offset; - } - if ((reg1 && GET_CODE (reg1) == MULT) - || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) - { - breg = reg2; - ireg = reg1; - } - else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) - { - breg = reg1; - ireg = reg2; - } - - if (ireg != 0 || breg != 0) - { - int scale = 1; - - if (addr != 0) - { - if (flag_pic) - output_pic_addr_const (file, addr, 0); - - else if (GET_CODE (addr) == LABEL_REF) - output_asm_label (addr); - - else - output_addr_const (file, addr); - } - - if (ireg != 0 && GET_CODE (ireg) == MULT) - { - scale = INTVAL (XEXP (ireg, 1)); - ireg = XEXP (ireg, 0); - } - - /* The stack pointer can only appear as a base register, - never an index register, so exchange the regs if it is wrong. */ - - if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM) - { - rtx tmp; - - tmp = breg; - breg = ireg; - ireg = tmp; - } - - /* output breg+ireg*scale */ - PRINT_B_I_S (breg, ireg, scale, file); - break; - } - - case MULT: - { - int scale; - if (GET_CODE (XEXP (addr, 0)) == CONST_INT) - { - scale = INTVAL (XEXP (addr, 0)); - ireg = XEXP (addr, 1); - } - else - { - scale = INTVAL (XEXP (addr, 1)); - ireg = XEXP (addr, 0); - } - output_addr_const (file, const0_rtx); - PRINT_B_I_S ((rtx) 0, ireg, scale, file); - } - break; - - default: - if (GET_CODE (addr) == CONST_INT - && INTVAL (addr) < 0x8000 - && INTVAL (addr) >= -0x8000) - fprintf (file, "%d", INTVAL (addr)); - else - { - if (flag_pic) - output_pic_addr_const (file, addr, 0); - else - output_addr_const (file, addr); - } - } -} - -/* Set the cc_status for the results of an insn whose pattern is EXP. - On the 80386, we assume that only test and compare insns, as well - as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT, - ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully. - Also, we assume that jumps, moves and sCOND don't affect the condition - codes. All else clobbers the condition codes, by assumption. - - We assume that ALL integer add, minus, etc. instructions effect the - condition codes. This MUST be consistent with i386.md. - - We don't record any float test or compare - the redundant test & - compare check in final.c does not handle stack-like regs correctly. */ - -void -notice_update_cc (exp) - rtx exp; -{ - if (GET_CODE (exp) == SET) - { - /* Jumps do not alter the cc's. */ - if (SET_DEST (exp) == pc_rtx) - return; - /* Moving register or memory into a register: - it doesn't alter the cc's, but it might invalidate - the RTX's which we remember the cc's came from. - (Note that moving a constant 0 or 1 MAY set the cc's). */ - if (REG_P (SET_DEST (exp)) - && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM - || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<')) - { - if (cc_status.value1 - && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1)) - cc_status.value1 = 0; - if (cc_status.value2 - && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2)) - cc_status.value2 = 0; - return; - } - /* Moving register into memory doesn't alter the cc's. - It may invalidate the RTX's which we remember the cc's came from. */ - if (GET_CODE (SET_DEST (exp)) == MEM - && (REG_P (SET_SRC (exp)) - || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<')) - { - if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM) - cc_status.value1 = 0; - if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM) - cc_status.value2 = 0; - return; - } - /* Function calls clobber the cc's. */ - else if (GET_CODE (SET_SRC (exp)) == CALL) - { - CC_STATUS_INIT; - return; - } - /* Tests and compares set the cc's in predictable ways. */ - else if (SET_DEST (exp) == cc0_rtx) - { - CC_STATUS_INIT; - cc_status.value1 = SET_SRC (exp); - return; - } - /* Certain instructions effect the condition codes. */ - else if (GET_MODE (SET_SRC (exp)) == SImode - || GET_MODE (SET_SRC (exp)) == HImode - || GET_MODE (SET_SRC (exp)) == QImode) - switch (GET_CODE (SET_SRC (exp))) - { - case ASHIFTRT: case LSHIFTRT: - case ASHIFT: - /* Shifts on the 386 don't set the condition codes if the - shift count is zero. */ - if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT) - { - CC_STATUS_INIT; - break; - } - /* We assume that the CONST_INT is non-zero (this rtx would - have been deleted if it were zero. */ - - case PLUS: case MINUS: case NEG: - case AND: case IOR: case XOR: - cc_status.flags = CC_NO_OVERFLOW; - cc_status.value1 = SET_SRC (exp); - cc_status.value2 = SET_DEST (exp); - break; - - default: - CC_STATUS_INIT; - } - else - { - CC_STATUS_INIT; - } - } - else if (GET_CODE (exp) == PARALLEL - && GET_CODE (XVECEXP (exp, 0, 0)) == SET) - { - if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx) - return; - if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx) - { - CC_STATUS_INIT; - if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0)))) - cc_status.flags |= CC_IN_80387; - else - cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0)); - return; - } - CC_STATUS_INIT; - } - else - { - CC_STATUS_INIT; - } -} - -/* Split one or more DImode RTL references into pairs of SImode - references. The RTL can be REG, offsettable MEM, integer constant, or - CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to - split and "num" is its length. lo_half and hi_half are output arrays - that parallel "operands". */ - -void -split_di (operands, num, lo_half, hi_half) - rtx operands[]; - int num; - rtx lo_half[], hi_half[]; -{ - while (num--) - { - if (GET_CODE (operands[num]) == REG) - { - lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num])); - hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1); - } - else if (CONSTANT_P (operands[num])) - { - split_double (operands[num], &lo_half[num], &hi_half[num]); - } - else if (offsettable_memref_p (operands[num])) - { - lo_half[num] = operands[num]; - hi_half[num] = adj_offsettable_operand (operands[num], 4); - } - else - abort(); - } -} - -/* Return 1 if this is a valid binary operation on a 387. - OP is the expression matched, and MODE is its mode. */ - -int -binary_387_op (op, mode) - register rtx op; - enum machine_mode mode; -{ - if (mode != VOIDmode && mode != GET_MODE (op)) - return 0; - - switch (GET_CODE (op)) - { - case PLUS: - case MINUS: - case MULT: - case DIV: - return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT; - - default: - return 0; - } -} - - -/* Return 1 if this is a valid shift or rotate operation on a 386. - OP is the expression matched, and MODE is its mode. */ - -int -shift_op (op, mode) - register rtx op; - enum machine_mode mode; -{ - rtx operand = XEXP (op, 0); - - if (mode != VOIDmode && mode != GET_MODE (op)) - return 0; - - if (GET_MODE (operand) != GET_MODE (op) - || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT) - return 0; - - return (GET_CODE (op) == ASHIFT - || GET_CODE (op) == ASHIFTRT - || GET_CODE (op) == LSHIFTRT - || GET_CODE (op) == ROTATE - || GET_CODE (op) == ROTATERT); -} - -/* Return 1 if OP is COMPARE rtx with mode VOIDmode. - MODE is not used. */ - -int -VOIDmode_compare_op (op, mode) - register rtx op; - enum machine_mode mode; -{ - return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode; -} - -/* Output code to perform a 387 binary operation in INSN, one of PLUS, - MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3] - is the expression of the binary operation. The output may either be - emitted here, or returned to the caller, like all output_* functions. - - There is no guarantee that the operands are the same mode, as they - might be within FLOAT or FLOAT_EXTEND expressions. */ - -char * -output_387_binary_op (insn, operands) - rtx insn; - rtx *operands; -{ - rtx temp; - char *base_op; - static char buf[100]; - - switch (GET_CODE (operands[3])) - { - case PLUS: - if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT - || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT) - base_op = "fiadd"; - else - base_op = "fadd"; - break; - - case MINUS: - if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT - || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT) - base_op = "fisub"; - else - base_op = "fsub"; - break; - - case MULT: - if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT - || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT) - base_op = "fimul"; - else - base_op = "fmul"; - break; - - case DIV: - if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT - || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT) - base_op = "fidiv"; - else - base_op = "fdiv"; - break; - - default: - abort (); - } - - strcpy (buf, base_op); - - switch (GET_CODE (operands[3])) - { - case MULT: - case PLUS: - if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2])) - { - temp = operands[2]; - operands[2] = operands[1]; - operands[1] = temp; - } - - if (GET_CODE (operands[2]) == MEM) - return strcat (buf, AS1 (%z2,%2)); - - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1))); - RET; - } - else if (NON_STACK_REG_P (operands[2])) - { - output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1))); - RET; - } - - if (find_regno_note (insn, REG_DEAD, REGNO (operands[2]))) - return strcat (buf, AS2 (p,%2,%0)); - - if (STACK_TOP_P (operands[0])) - return strcat (buf, AS2C (%y2,%0)); - else - return strcat (buf, AS2C (%2,%0)); - - case MINUS: - case DIV: - if (GET_CODE (operands[1]) == MEM) - return strcat (buf, AS1 (r%z1,%1)); - - if (GET_CODE (operands[2]) == MEM) - return strcat (buf, AS1 (%z2,%2)); - - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1))); - RET; - } - else if (NON_STACK_REG_P (operands[2])) - { - output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1))); - RET; - } - - if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2])) - abort (); - - if (find_regno_note (insn, REG_DEAD, REGNO (operands[2]))) - return strcat (buf, AS2 (rp,%2,%0)); - - if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) - return strcat (buf, AS2 (p,%1,%0)); - - if (STACK_TOP_P (operands[0])) - { - if (STACK_TOP_P (operands[1])) - return strcat (buf, AS2C (%y2,%0)); - else - return strcat (buf, AS2 (r,%y1,%0)); - } - else if (STACK_TOP_P (operands[1])) - return strcat (buf, AS2C (%1,%0)); - else - return strcat (buf, AS2 (r,%2,%0)); - - default: - abort (); - } -} - -/* Output code for INSN to convert a float to a signed int. OPERANDS - are the insn operands. The output may be SFmode or DFmode and the - input operand may be SImode or DImode. As a special case, make sure - that the 387 stack top dies if the output mode is DImode, because the - hardware requires this. */ - -char * -output_fix_trunc (insn, operands) - rtx insn; - rtx *operands; -{ - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - rtx xops[2]; - - if (! STACK_TOP_P (operands[1]) || - (GET_MODE (operands[0]) == DImode && ! stack_top_dies)) - abort (); - - xops[0] = GEN_INT (12); - xops[1] = operands[4]; - - output_asm_insn (AS1 (fnstc%W2,%2), operands); - output_asm_insn (AS2 (mov%L2,%2,%4), operands); - output_asm_insn (AS2 (mov%B1,%0,%h1), xops); - output_asm_insn (AS2 (mov%L4,%4,%3), operands); - output_asm_insn (AS1 (fldc%W3,%3), operands); - - if (NON_STACK_REG_P (operands[0])) - output_to_reg (operands[0], stack_top_dies); - else if (GET_CODE (operands[0]) == MEM) - { - if (stack_top_dies) - output_asm_insn (AS1 (fistp%z0,%0), operands); - else - output_asm_insn (AS1 (fist%z0,%0), operands); - } - else - abort (); - - return AS1 (fldc%W2,%2); -} - -/* Output code for INSN to compare OPERANDS. The two operands might - not have the same mode: one might be within a FLOAT or FLOAT_EXTEND - expression. If the compare is in mode CCFPEQmode, use an opcode that - will not fault if a qNaN is present. */ - -char * -output_float_compare (insn, operands) - rtx insn; - rtx *operands; -{ - int stack_top_dies; - rtx body = XVECEXP (PATTERN (insn), 0, 0); - int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode; - - if (! STACK_TOP_P (operands[0])) - abort (); - - stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - if (STACK_REG_P (operands[1]) - && stack_top_dies - && find_regno_note (insn, REG_DEAD, REGNO (operands[1])) - && REGNO (operands[1]) != FIRST_STACK_REG) - { - /* If both the top of the 387 stack dies, and the other operand - is also a stack register that dies, then this must be a - `fcompp' float compare */ - - if (unordered_compare) - output_asm_insn ("fucompp", operands); - else - output_asm_insn ("fcompp", operands); - } - else - { - static char buf[100]; - - /* Decide if this is the integer or float compare opcode, or the - unordered float compare. */ - - if (unordered_compare) - strcpy (buf, "fucom"); - else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT) - strcpy (buf, "fcom"); - else - strcpy (buf, "ficom"); - - /* Modify the opcode if the 387 stack is to be popped. */ - - if (stack_top_dies) - strcat (buf, "p"); - - if (NON_STACK_REG_P (operands[1])) - output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1))); - else - output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands); - } - - /* Now retrieve the condition code. */ - - return output_fp_cc0_set (insn); -} - -/* Output opcodes to transfer the results of FP compare or test INSN - from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the - result of the compare or test is unordered, no comparison operator - succeeds except NE. Return an output template, if any. */ - -char * -output_fp_cc0_set (insn) - rtx insn; -{ - rtx xops[3]; - rtx unordered_label; - rtx next; - enum rtx_code code; - - xops[0] = gen_rtx (REG, HImode, 0); - output_asm_insn (AS1 (fnsts%W0,%0), xops); - - if (! TARGET_IEEE_FP) - return "sahf"; - - next = next_cc0_user (insn); - if (next == NULL_RTX) - abort (); - - if (GET_CODE (next) == JUMP_INSN - && GET_CODE (PATTERN (next)) == SET - && SET_DEST (PATTERN (next)) == pc_rtx - && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE) - { - code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)); - } - else if (GET_CODE (PATTERN (next)) == SET) - { - code = GET_CODE (SET_SRC (PATTERN (next))); - } - else - abort (); - - xops[0] = gen_rtx (REG, QImode, 0); - - switch (code) - { - case GT: - xops[1] = GEN_INT (0x45); - output_asm_insn (AS2 (and%B0,%1,%h0), xops); - /* je label */ - break; - - case LT: - xops[1] = GEN_INT (0x45); - xops[2] = GEN_INT (0x01); - output_asm_insn (AS2 (and%B0,%1,%h0), xops); - output_asm_insn (AS2 (cmp%B0,%2,%h0), xops); - /* je label */ - break; - - case GE: - xops[1] = GEN_INT (0x05); - output_asm_insn (AS2 (and%B0,%1,%h0), xops); - /* je label */ - break; - - case LE: - xops[1] = GEN_INT (0x45); - xops[2] = GEN_INT (0x40); - output_asm_insn (AS2 (and%B0,%1,%h0), xops); - output_asm_insn (AS1 (dec%B0,%h0), xops); - output_asm_insn (AS2 (cmp%B0,%2,%h0), xops); - /* jb label */ - break; - - case EQ: - xops[1] = GEN_INT (0x45); - xops[2] = GEN_INT (0x40); - output_asm_insn (AS2 (and%B0,%1,%h0), xops); - output_asm_insn (AS2 (cmp%B0,%2,%h0), xops); - /* je label */ - break; - - case NE: - xops[1] = GEN_INT (0x44); - xops[2] = GEN_INT (0x40); - output_asm_insn (AS2 (and%B0,%1,%h0), xops); - output_asm_insn (AS2 (xor%B0,%2,%h0), xops); - /* jne label */ - break; - - case GTU: - case LTU: - case GEU: - case LEU: - default: - abort (); - } - RET; -} - -#define MAX_386_STACK_LOCALS 2 - -static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS]; - -/* Define the structure for the machine field in struct function. */ -struct machine_function -{ - rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS]; -}; - -/* Functions to save and restore i386_stack_locals. - These will be called, via pointer variables, - from push_function_context and pop_function_context. */ - -void -save_386_machine_status (p) - struct function *p; -{ - p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals); - bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals, - sizeof i386_stack_locals); -} - -void -restore_386_machine_status (p) - struct function *p; -{ - bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals, - sizeof i386_stack_locals); - free (p->machine); -} - -/* Clear stack slot assignments remembered from previous functions. - This is called from INIT_EXPANDERS once before RTL is emitted for each - function. */ - -void -clear_386_stack_locals () -{ - enum machine_mode mode; - int n; - - for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE; - mode = (enum machine_mode) ((int) mode + 1)) - for (n = 0; n < MAX_386_STACK_LOCALS; n++) - i386_stack_locals[(int) mode][n] = NULL_RTX; - - /* Arrange to save and restore i386_stack_locals around nested functions. */ - save_machine_status = save_386_machine_status; - restore_machine_status = restore_386_machine_status; -} - -/* Return a MEM corresponding to a stack slot with mode MODE. - Allocate a new slot if necessary. - - The RTL for a function can have several slots available: N is - which slot to use. */ - -rtx -assign_386_stack_local (mode, n) - enum machine_mode mode; - int n; -{ - if (n < 0 || n >= MAX_386_STACK_LOCALS) - abort (); - - if (i386_stack_locals[(int) mode][n] == NULL_RTX) - i386_stack_locals[(int) mode][n] - = assign_stack_local (mode, GET_MODE_SIZE (mode), 0); - - return i386_stack_locals[(int) mode][n]; -} diff --git a/support/cpp/i386/i386.h b/support/cpp/i386/i386.h deleted file mode 100644 index 1e44218e..00000000 --- a/support/cpp/i386/i386.h +++ /dev/null @@ -1,1934 +0,0 @@ -/* Definitions of target machine for GNU compiler for Intel X86 - (386, 486, Pentium). - Copyright (C) 1988, 1992, 1994, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* The purpose of this file is to define the characteristics of the i386, - independent of assembler syntax or operating system. - - Three other files build on this one to describe a specific assembler syntax: - bsd386.h, att386.h, and sun386.h. - - The actual tm.h file for a particular system should include - this file, and then the file for the appropriate assembler syntax. - - Many macros that specify assembler syntax are omitted entirely from - this file because they really belong in the files for particular - assemblers. These include AS1, AS2, AS3, RP, IP, LPREFIX, L_SIZE, - PUT_OP_SIZE, USE_STAR, ADDR_BEG, ADDR_END, PRINT_IREG, PRINT_SCALE, - PRINT_B_I_S, and many that start with ASM_ or end in ASM_OP. */ - -/* Names to predefine in the preprocessor for this target machine. */ - -#define I386 1 - -/* Stubs for half-pic support if not OSF/1 reference platform. */ - -#ifndef HALF_PIC_P -#define HALF_PIC_P() 0 -#define HALF_PIC_NUMBER_PTRS 0 -#define HALF_PIC_NUMBER_REFS 0 -#define HALF_PIC_ENCODE(DECL) -#define HALF_PIC_DECLARE(NAME) -#define HALF_PIC_INIT() error ("half-pic init called on systems that don't support it.") -#define HALF_PIC_ADDRESS_P(X) 0 -#define HALF_PIC_PTR(X) X -#define HALF_PIC_FINISH(STREAM) -#endif - -/* Run-time compilation parameters selecting different hardware subsets. */ - -extern int target_flags; - -/* Macros used in the machine description to test the flags. */ - -/* configure can arrange to make this 2, to force a 486. */ -#ifndef TARGET_CPU_DEFAULT -#define TARGET_CPU_DEFAULT 0 -#endif - -/* Masks for the -m switches */ -#define MASK_80387 000000000001 /* Hardware floating point */ -#define MASK_486 000000000002 /* 80486 specific */ -#define MASK_NOTUSED1 000000000004 /* bit not currently used */ -#define MASK_RTD 000000000010 /* Use ret that pops args */ -#define MASK_ALIGN_DOUBLE 000000000020 /* align doubles to 2 word boundary */ -#define MASK_SVR3_SHLIB 000000000040 /* Uninit locals into bss */ -#define MASK_IEEE_FP 000000000100 /* IEEE fp comparisons */ -#define MASK_FLOAT_RETURNS 000000000200 /* Return float in st(0) */ -#define MASK_NO_FANCY_MATH_387 000000000400 /* Disable sin, cos, sqrt */ - - /* Temporary codegen switches */ -#define MASK_DEBUG_ADDR 000001000000 /* Debug GO_IF_LEGITIMATE_ADDRESS */ -#define MASK_NO_WIDE_MULTIPLY 000002000000 /* Disable 32x32->64 multiplies */ -#define MASK_NO_MOVE 000004000000 /* Don't generate mem->mem */ -#define MASK_DEBUG_ARG 000010000000 /* Debug function_arg */ - -/* Use the floating point instructions */ -#define TARGET_80387 (target_flags & MASK_80387) - -/* Compile using ret insn that pops args. - This will not work unless you use prototypes at least - for all functions that can take varying numbers of args. */ -#define TARGET_RTD (target_flags & MASK_RTD) - -/* Align doubles to a two word boundary. This breaks compatibility with - the published ABI's for structures containing doubles, but produces - faster code on the pentium. */ -#define TARGET_ALIGN_DOUBLE (target_flags & MASK_ALIGN_DOUBLE) - -/* Put uninitialized locals into bss, not data. - Meaningful only on svr3. */ -#define TARGET_SVR3_SHLIB (target_flags & MASK_SVR3_SHLIB) - -/* Use IEEE floating point comparisons. These handle correctly the cases - where the result of a comparison is unordered. Normally SIGFPE is - generated in such cases, in which case this isn't needed. */ -#define TARGET_IEEE_FP (target_flags & MASK_IEEE_FP) - -/* Functions that return a floating point value may return that value - in the 387 FPU or in 386 integer registers. If set, this flag causes - the 387 to be used, which is compatible with most calling conventions. */ -#define TARGET_FLOAT_RETURNS_IN_80387 (target_flags & MASK_FLOAT_RETURNS) - -/* Disable generation of FP sin, cos and sqrt operations for 387. - This is because FreeBSD lacks these in the math-emulator-code */ -#define TARGET_NO_FANCY_MATH_387 (target_flags & MASK_NO_FANCY_MATH_387) - -/* Temporary switches for tuning code generation */ - -/* Disable 32x32->64 bit multiplies that are used for long long multiplies - and division by constants, but sometimes cause reload problems. */ -#define TARGET_NO_WIDE_MULTIPLY (target_flags & MASK_NO_WIDE_MULTIPLY) -#define TARGET_WIDE_MULTIPLY (!TARGET_NO_WIDE_MULTIPLY) - -/* Debug GO_IF_LEGITIMATE_ADDRESS */ -#define TARGET_DEBUG_ADDR (target_flags & MASK_DEBUG_ADDR) - -/* Debug FUNCTION_ARG macros */ -#define TARGET_DEBUG_ARG (target_flags & MASK_DEBUG_ARG) - -/* Hack macros for tuning code generation */ -#define TARGET_MOVE ((target_flags & MASK_NO_MOVE) == 0) /* Don't generate memory->memory */ - -/* Specific hardware switches */ -#define TARGET_486 (target_flags & MASK_486) /* 80486DX, 80486SX, 80486DX[24] */ -#define TARGET_386 (!TARGET_486) /* 80386 */ - -#define TARGET_SWITCHES \ -{ { "80387", MASK_80387 }, \ - { "no-80387", -MASK_80387 }, \ - { "hard-float", MASK_80387 }, \ - { "soft-float", -MASK_80387 }, \ - { "no-soft-float", MASK_80387 }, \ - { "386", -MASK_486 }, \ - { "no-386", MASK_486 }, \ - { "486", MASK_486 }, \ - { "no-486", -MASK_486 }, \ - { "rtd", MASK_RTD }, \ - { "no-rtd", -MASK_RTD }, \ - { "align-double", MASK_ALIGN_DOUBLE }, \ - { "no-align-double", -MASK_ALIGN_DOUBLE }, \ - { "svr3-shlib", MASK_SVR3_SHLIB }, \ - { "no-svr3-shlib", -MASK_SVR3_SHLIB }, \ - { "ieee-fp", MASK_IEEE_FP }, \ - { "no-ieee-fp", -MASK_IEEE_FP }, \ - { "fp-ret-in-387", MASK_FLOAT_RETURNS }, \ - { "no-fp-ret-in-387", -MASK_FLOAT_RETURNS }, \ - { "no-fancy-math-387", MASK_NO_FANCY_MATH_387 }, \ - { "fancy-math-387", -MASK_NO_FANCY_MATH_387 }, \ - { "no-wide-multiply", MASK_NO_WIDE_MULTIPLY }, \ - { "wide-multiply", -MASK_NO_WIDE_MULTIPLY }, \ - { "debug-addr", MASK_DEBUG_ADDR }, \ - { "no-debug-addr", -MASK_DEBUG_ADDR }, \ - { "move", -MASK_NO_MOVE }, \ - { "no-move", MASK_NO_MOVE }, \ - { "debug-arg", MASK_DEBUG_ARG }, \ - { "no-debug-arg", -MASK_DEBUG_ARG }, \ - SUBTARGET_SWITCHES \ - { "", TARGET_DEFAULT | TARGET_CPU_DEFAULT}} - -/* This macro is similar to `TARGET_SWITCHES' but defines names of - command options that have values. Its definition is an - initializer with a subgrouping for each command option. - - Each subgrouping contains a string constant, that defines the - fixed part of the option name, and the address of a variable. The - variable, type `char *', is set to the variable part of the given - option if the fixed part matches. The actual option name is made - by appending `-m' to the specified name. */ -#define TARGET_OPTIONS \ -{ { "reg-alloc=", &i386_reg_alloc_order }, \ - { "regparm=", &i386_regparm_string }, \ - { "align-loops=", &i386_align_loops_string }, \ - { "align-jumps=", &i386_align_jumps_string }, \ - { "align-functions=", &i386_align_funcs_string }, \ - SUBTARGET_OPTIONS \ -} - -/* Sometimes certain combinations of command options do not make - sense on a particular target machine. You can define a macro - `OVERRIDE_OPTIONS' to take account of this. This macro, if - defined, is executed once just after all the command options have - been parsed. - - Don't use this macro to turn on various extra optimizations for - `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */ - -#define OVERRIDE_OPTIONS override_options () - -/* These are meant to be redefined in the host dependent files */ -#define SUBTARGET_SWITCHES -#define SUBTARGET_OPTIONS - - -/* target machine storage layout */ - -/* Define for XFmode extended real floating point support. - This will automatically cause REAL_ARITHMETIC to be defined. */ -#define LONG_DOUBLE_TYPE_SIZE 96 - -/* Define if you don't want extended real, but do want to use the - software floating point emulator for REAL_ARITHMETIC and - decimal <-> binary conversion. */ -/* #define REAL_ARITHMETIC */ - -/* Define this if most significant byte of a word is the lowest numbered. */ -/* That is true on the 80386. */ - -#define BITS_BIG_ENDIAN 0 - -/* Define this if most significant byte of a word is the lowest numbered. */ -/* That is not true on the 80386. */ -#define BYTES_BIG_ENDIAN 0 - -/* Define this if most significant word of a multiword number is the lowest - numbered. */ -/* Not true for 80386 */ -#define WORDS_BIG_ENDIAN 0 - -/* number of bits in an addressable storage unit */ -#define BITS_PER_UNIT 8 - -/* Width in bits of a "word", which is the contents of a machine register. - Note that this is not necessarily the width of data type `int'; - if using 16-bit ints on a 80386, this would still be 32. - But on a machine with 16-bit registers, this would be 16. */ -#define BITS_PER_WORD 32 - -/* Width of a word, in units (bytes). */ -#define UNITS_PER_WORD 4 - -/* Width in bits of a pointer. - See also the macro `Pmode' defined below. */ -#define POINTER_SIZE 32 - -/* Allocation boundary (in *bits*) for storing arguments in argument list. */ -#define PARM_BOUNDARY 32 - -/* Boundary (in *bits*) on which stack pointer should be aligned. */ -#define STACK_BOUNDARY 32 - -/* Allocation boundary (in *bits*) for the code of a function. - For i486, we get better performance by aligning to a cache - line (i.e. 16 byte) boundary. */ -#define FUNCTION_BOUNDARY (1 << (i386_align_funcs + 3)) - -/* Alignment of field after `int : 0' in a structure. */ - -#define EMPTY_FIELD_BOUNDARY 32 - -/* Minimum size in bits of the largest boundary to which any - and all fundamental data types supported by the hardware - might need to be aligned. No data type wants to be aligned - rounder than this. The i386 supports 64-bit floating point - quantities, but these can be aligned on any 32-bit boundary. - The published ABIs say that doubles should be aligned on word - boundaries, but the Pentium gets better performance with them - aligned on 64 bit boundaries. */ -#define BIGGEST_ALIGNMENT (TARGET_ALIGN_DOUBLE ? 64 : 32) - -/* Set this non-zero if move instructions will actually fail to work - when given unaligned data. */ -#define STRICT_ALIGNMENT 0 - -/* If bit field type is int, don't let it cross an int, - and give entire struct the alignment of an int. */ -/* Required on the 386 since it doesn't have bitfield insns. */ -#define PCC_BITFIELD_TYPE_MATTERS 1 - -/* Maximum power of 2 that code can be aligned to. */ -#define MAX_CODE_ALIGN 6 /* 64 byte alignment */ - -/* Align loop starts for optimal branching. */ -#define ASM_OUTPUT_LOOP_ALIGN(FILE) ASM_OUTPUT_ALIGN (FILE, i386_align_loops) - -/* This is how to align an instruction for optimal branching. - On i486 we'll get better performance by aligning on a - cache line (i.e. 16 byte) boundary. */ -#define ASM_OUTPUT_ALIGN_CODE(FILE) ASM_OUTPUT_ALIGN ((FILE), i386_align_jumps) - - -/* Standard register usage. */ - -/* This processor has special stack-like registers. See reg-stack.c - for details. */ - -#define STACK_REGS - -/* Number of actual hardware registers. - The hardware registers are assigned numbers for the compiler - from 0 to just below FIRST_PSEUDO_REGISTER. - All registers that the compiler knows about must be given numbers, - even those that are not normally considered general registers. - - In the 80386 we give the 8 general purpose registers the numbers 0-7. - We number the floating point registers 8-15. - Note that registers 0-7 can be accessed as a short or int, - while only 0-3 may be used with byte `mov' instructions. - - Reg 16 does not correspond to any hardware register, but instead - appears in the RTL as an argument pointer prior to reload, and is - eliminated during reloading in favor of either the stack or frame - pointer. */ - -#define FIRST_PSEUDO_REGISTER 17 - -/* 1 for registers that have pervasive standard uses - and are not available for the register allocator. - On the 80386, the stack pointer is such, as is the arg pointer. */ -#define FIXED_REGISTERS \ -/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \ -{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 } - -/* 1 for registers not available across function calls. - These must include the FIXED_REGISTERS and also any - registers that can be used without being saved. - The latter must include the registers where values are returned - and the register where structure-value addresses are passed. - Aside from that, you can include as many other registers as you like. */ - -#define CALL_USED_REGISTERS \ -/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \ -{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } - -/* Order in which to allocate registers. Each register must be - listed once, even those in FIXED_REGISTERS. List frame pointer - late and fixed registers last. Note that, in general, we prefer - registers listed in CALL_USED_REGISTERS, keeping the others - available for storage of persistent values. - - Three different versions of REG_ALLOC_ORDER have been tried: - - If the order is edx, ecx, eax, ... it produces a slightly faster compiler, - but slower code on simple functions returning values in eax. - - If the order is eax, ecx, edx, ... it causes reload to abort when compiling - perl 4.036 due to not being able to create a DImode register (to hold a 2 - word union). - - If the order is eax, edx, ecx, ... it produces better code for simple - functions, and a slightly slower compiler. Users complained about the code - generated by allocating edx first, so restore the 'natural' order of things. */ - -#define REG_ALLOC_ORDER \ -/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \ -{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 } - -/* A C statement (sans semicolon) to choose the order in which to - allocate hard registers for pseudo-registers local to a basic - block. - - Store the desired register order in the array `reg_alloc_order'. - Element 0 should be the register to allocate first; element 1, the - next register; and so on. - - The macro body should not assume anything about the contents of - `reg_alloc_order' before execution of the macro. - - On most machines, it is not necessary to define this macro. */ - -#define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc () - -/* Macro to conditionally modify fixed_regs/call_used_regs. */ -#define CONDITIONAL_REGISTER_USAGE \ - { \ - if (flag_pic) \ - { \ - fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ - call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ - } \ - if (! TARGET_80387 && ! TARGET_FLOAT_RETURNS_IN_80387) \ - { \ - int i; \ - HARD_REG_SET x; \ - COPY_HARD_REG_SET (x, reg_class_contents[(int)FLOAT_REGS]); \ - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ ) \ - if (TEST_HARD_REG_BIT (x, i)) \ - fixed_regs[i] = call_used_regs[i] = 1; \ - } \ - } - -/* Return number of consecutive hard regs needed starting at reg REGNO - to hold something of mode MODE. - This is ordinarily the length in words of a value of mode MODE - but can be less for certain modes in special long registers. - - Actually there are no two word move instructions for consecutive - registers. And only registers 0-3 may have mov byte instructions - applied to them. - */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - (FP_REGNO_P (REGNO) ? 1 \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - -/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. - On the 80386, the first 4 cpu registers can hold any mode - while the floating point registers may hold only floating point. - Make it clear that the fp regs could not hold a 16-byte float. */ - -/* The casts to int placate a compiler on a microvax, - for cross-compiler testing. */ - -#define HARD_REGNO_MODE_OK(REGNO, MODE) \ - ((REGNO) < 2 ? 1 \ - : (REGNO) < 4 ? 1 \ - : FP_REGNO_P (REGNO) \ - ? (((int) GET_MODE_CLASS (MODE) == (int) MODE_FLOAT \ - || (int) GET_MODE_CLASS (MODE) == (int) MODE_COMPLEX_FLOAT) \ - && GET_MODE_UNIT_SIZE (MODE) <= 12) \ - : (int) (MODE) != (int) QImode) - -/* Value is 1 if it is a good idea to tie two pseudo registers - when one has mode MODE1 and one has mode MODE2. - If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, - for any hard reg, then this must be 0 for correct output. */ - -#define MODES_TIEABLE_P(MODE1, MODE2) ((MODE1) == (MODE2)) - -/* A C expression returning the cost of moving data from a register of class - CLASS1 to one of CLASS2. - - On the i386, copying between floating-point and fixed-point - registers is expensive. */ - -#define REGISTER_MOVE_COST(CLASS1, CLASS2) \ - (((FLOAT_CLASS_P (CLASS1) && ! FLOAT_CLASS_P (CLASS2)) \ - || (! FLOAT_CLASS_P (CLASS1) && FLOAT_CLASS_P (CLASS2))) ? 10 \ - : 2) - -/* Specify the registers used for certain standard purposes. - The values of these macros are register numbers. */ - -/* on the 386 the pc register is %eip, and is not usable as a general - register. The ordinary mov instructions won't work */ -/* #define PC_REGNUM */ - -/* Register to use for pushing function arguments. */ -#define STACK_POINTER_REGNUM 7 - -/* Base register for access to local variables of the function. */ -#define FRAME_POINTER_REGNUM 6 - -/* First floating point reg */ -#define FIRST_FLOAT_REG 8 - -/* First & last stack-like regs */ -#define FIRST_STACK_REG FIRST_FLOAT_REG -#define LAST_STACK_REG (FIRST_FLOAT_REG + 7) - -/* Value should be nonzero if functions must have frame pointers. - Zero means the frame pointer need not be set up (and parms - may be accessed via the stack pointer) in functions that seem suitable. - This is computed in `reload', in reload1.c. */ -#define FRAME_POINTER_REQUIRED 0 - -/* Base register for access to arguments of the function. */ -#define ARG_POINTER_REGNUM 16 - -/* Register in which static-chain is passed to a function. */ -#define STATIC_CHAIN_REGNUM 2 - -/* Register to hold the addressing base for position independent - code access to data items. */ -#define PIC_OFFSET_TABLE_REGNUM 3 - -/* Register in which address to store a structure value - arrives in the function. On the 386, the prologue - copies this from the stack to register %eax. */ -#define STRUCT_VALUE_INCOMING 0 - -/* Place in which caller passes the structure value address. - 0 means push the value on the stack like an argument. */ -#define STRUCT_VALUE 0 - -/* A C expression which can inhibit the returning of certain function - values in registers, based on the type of value. A nonzero value - says to return the function value in memory, just as large - structures are always returned. Here TYPE will be a C expression - of type `tree', representing the data type of the value. - - Note that values of mode `BLKmode' must be explicitly handled by - this macro. Also, the option `-fpcc-struct-return' takes effect - regardless of this macro. On most systems, it is possible to - leave the macro undefined; this causes a default definition to be - used, whose value is the constant 1 for `BLKmode' values, and 0 - otherwise. - - Do not use this macro to indicate that structures and unions - should always be returned in memory. You should instead use - `DEFAULT_PCC_STRUCT_RETURN' to indicate this. */ - -#define RETURN_IN_MEMORY(TYPE) \ - ((TYPE_MODE (TYPE) == BLKmode) || int_size_in_bytes (TYPE) > 12) - - -/* Define the classes of registers for register constraints in the - machine description. Also define ranges of constants. - - One of the classes must always be named ALL_REGS and include all hard regs. - If there is more than one class, another class must be named NO_REGS - and contain no registers. - - The name GENERAL_REGS must be the name of a class (or an alias for - another name such as ALL_REGS). This is the class of registers - that is allowed by "g" or "r" in a register constraint. - Also, registers outside this class are allocated only when - instructions express preferences for them. - - The classes must be numbered in nondecreasing order; that is, - a larger-numbered class must never be contained completely - in a smaller-numbered class. - - For any two classes, it is very desirable that there be another - class that represents their union. - - It might seem that class BREG is unnecessary, since no useful 386 - opcode needs reg %ebx. But some systems pass args to the OS in ebx, - and the "b" register constraint is useful in asms for syscalls. */ - -//enum reg_class -//{ -// NO_REGS, -// AREG, DREG, CREG, BREG, -// AD_REGS, /* %eax/%edx for DImode */ -// Q_REGS, /* %eax %ebx %ecx %edx */ -// SIREG, DIREG, -// INDEX_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp */ -// GENERAL_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp %esp */ -// FP_TOP_REG, FP_SECOND_REG, /* %st(0) %st(1) */ -// FLOAT_REGS, -// ALL_REGS, LIM_REG_CLASSES -//}; - -#define N_REG_CLASSES (int) LIM_REG_CLASSES - -#define FLOAT_CLASS_P(CLASS) (reg_class_subset_p (CLASS, FLOAT_REGS)) - -/* Give names of register classes as strings for dump file. */ - -#define REG_CLASS_NAMES \ -{ "NO_REGS", \ - "AREG", "DREG", "CREG", "BREG", \ - "AD_REGS", \ - "Q_REGS", \ - "SIREG", "DIREG", \ - "INDEX_REGS", \ - "GENERAL_REGS", \ - "FP_TOP_REG", "FP_SECOND_REG", \ - "FLOAT_REGS", \ - "ALL_REGS" } - -/* Define which registers fit in which classes. - This is an initializer for a vector of HARD_REG_SET - of length N_REG_CLASSES. */ - -#define REG_CLASS_CONTENTS \ -{ 0, \ - 0x1, 0x2, 0x4, 0x8, /* AREG, DREG, CREG, BREG */ \ - 0x3, /* AD_REGS */ \ - 0xf, /* Q_REGS */ \ - 0x10, 0x20, /* SIREG, DIREG */ \ - 0x07f, /* INDEX_REGS */ \ - 0x100ff, /* GENERAL_REGS */ \ - 0x0100, 0x0200, /* FP_TOP_REG, FP_SECOND_REG */ \ - 0xff00, /* FLOAT_REGS */ \ - 0x1ffff } - -/* The same information, inverted: - Return the class number of the smallest class containing - reg number REGNO. This could be a conditional expression - or could index an array. */ - -#define REGNO_REG_CLASS(REGNO) (regclass_map[REGNO]) - -/* When defined, the compiler allows registers explicitly used in the - rtl to be used as spill registers but prevents the compiler from - extending the lifetime of these registers. */ - -#define SMALL_REGISTER_CLASSES - -#define QI_REG_P(X) \ - (REG_P (X) && REGNO (X) < 4) -#define NON_QI_REG_P(X) \ - (REG_P (X) && REGNO (X) >= 4 && REGNO (X) < FIRST_PSEUDO_REGISTER) - -#define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (REGNO (X))) -#define FP_REGNO_P(n) ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) - -#define STACK_REG_P(xop) (REG_P (xop) && \ - REGNO (xop) >= FIRST_STACK_REG && \ - REGNO (xop) <= LAST_STACK_REG) - -#define NON_STACK_REG_P(xop) (REG_P (xop) && ! STACK_REG_P (xop)) - -#define STACK_TOP_P(xop) (REG_P (xop) && REGNO (xop) == FIRST_STACK_REG) - -/* Try to maintain the accuracy of the death notes for regs satisfying the - following. Important for stack like regs, to know when to pop. */ - -/* #define PRESERVE_DEATH_INFO_REGNO_P(x) FP_REGNO_P(x) */ - -/* 1 if register REGNO can magically overlap other regs. - Note that nonzero values work only in very special circumstances. */ - -/* #define OVERLAPPING_REGNO_P(REGNO) FP_REGNO_P (REGNO) */ - -/* The class value for index registers, and the one for base regs. */ - -#define INDEX_REG_CLASS INDEX_REGS -#define BASE_REG_CLASS GENERAL_REGS - -/* Get reg_class from a letter such as appears in the machine description. */ - -#define REG_CLASS_FROM_LETTER(C) \ - ((C) == 'r' ? GENERAL_REGS : \ - (C) == 'q' ? Q_REGS : \ - (C) == 'f' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 \ - ? FLOAT_REGS \ - : NO_REGS) : \ - (C) == 't' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 \ - ? FP_TOP_REG \ - : NO_REGS) : \ - (C) == 'u' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 \ - ? FP_SECOND_REG \ - : NO_REGS) : \ - (C) == 'a' ? AREG : \ - (C) == 'b' ? BREG : \ - (C) == 'c' ? CREG : \ - (C) == 'd' ? DREG : \ - (C) == 'A' ? AD_REGS : \ - (C) == 'D' ? DIREG : \ - (C) == 'S' ? SIREG : NO_REGS) - -/* The letters I, J, K, L and M in a register constraint string - can be used to stand for particular ranges of immediate operands. - This macro defines what the ranges are. - C is the letter, and VALUE is a constant value. - Return 1 if VALUE is in the range specified by C. - - I is for non-DImode shifts. - J is for DImode shifts. - K and L are for an `andsi' optimization. - M is for shifts that can be executed by the "lea" opcode. - */ - -#define CONST_OK_FOR_LETTER_P(VALUE, C) \ - ((C) == 'I' ? (VALUE) >= 0 && (VALUE) <= 31 : \ - (C) == 'J' ? (VALUE) >= 0 && (VALUE) <= 63 : \ - (C) == 'K' ? (VALUE) == 0xff : \ - (C) == 'L' ? (VALUE) == 0xffff : \ - (C) == 'M' ? (VALUE) >= 0 && (VALUE) <= 3 : \ - (C) == 'N' ? (VALUE) >= 0 && (VALUE) <= 255 :\ - 0) - -/* Similar, but for floating constants, and defining letters G and H. - Here VALUE is the CONST_DOUBLE rtx itself. We allow constants even if - TARGET_387 isn't set, because the stack register converter may need to - load 0.0 into the function value register. */ - -#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ - ((C) == 'G' ? standard_80387_constant_p (VALUE) : 0) - -/* Place additional restrictions on the register class to use when it - is necessary to be able to hold a value of mode MODE in a reload - register for which class CLASS would ordinarily be used. */ - -#define LIMIT_RELOAD_CLASS(MODE, CLASS) \ - ((MODE) == QImode && ((CLASS) == ALL_REGS || (CLASS) == GENERAL_REGS) \ - ? Q_REGS : (CLASS)) - -/* Given an rtx X being reloaded into a reg required to be - in class CLASS, return the class of reg to actually use. - In general this is just CLASS; but on some machines - in some cases it is preferable to use a more restrictive class. - On the 80386 series, we prevent floating constants from being - reloaded into floating registers (since no move-insn can do that) - and we ensure that QImodes aren't reloaded into the esi or edi reg. */ - -/* Put float CONST_DOUBLE in the constant pool instead of fp regs. - QImode must go into class Q_REGS. - Narrow ALL_REGS to GENERAL_REGS. This supports allowing movsf and - movdf to do mem-to-mem moves through integer regs. */ - -#define PREFERRED_RELOAD_CLASS(X,CLASS) \ - (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode ? NO_REGS \ - : GET_MODE (X) == QImode && ! reg_class_subset_p (CLASS, Q_REGS) ? Q_REGS \ - : ((CLASS) == ALL_REGS \ - && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) ? GENERAL_REGS \ - : (CLASS)) - -/* If we are copying between general and FP registers, we need a memory - location. */ - -#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ - ((FLOAT_CLASS_P (CLASS1) && ! FLOAT_CLASS_P (CLASS2)) \ - || (! FLOAT_CLASS_P (CLASS1) && FLOAT_CLASS_P (CLASS2))) - -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ -/* On the 80386, this is the size of MODE in words, - except in the FP regs, where a single reg is always enough. */ -#define CLASS_MAX_NREGS(CLASS, MODE) \ - (FLOAT_CLASS_P (CLASS) ? 1 : \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - -/* A C expression whose value is nonzero if pseudos that have been - assigned to registers of class CLASS would likely be spilled - because registers of CLASS are needed for spill registers. - - The default value of this macro returns 1 if CLASS has exactly one - register and zero otherwise. On most machines, this default - should be used. Only define this macro to some other expression - if pseudo allocated by `local-alloc.c' end up in memory because - their hard registers were needed for spill registers. If this - macro returns nonzero for those classes, those pseudos will only - be allocated by `global.c', which knows how to reallocate the - pseudo to another register. If there would not be another - register available for reallocation, you should not change the - definition of this macro since the only effect of such a - definition would be to slow down register allocation. */ - -#define CLASS_LIKELY_SPILLED_P(CLASS) \ - (((CLASS) == AREG) \ - || ((CLASS) == DREG) \ - || ((CLASS) == CREG) \ - || ((CLASS) == BREG) \ - || ((CLASS) == AD_REGS) \ - || ((CLASS) == SIREG) \ - || ((CLASS) == DIREG)) - - -/* Stack layout; function entry, exit and calling. */ - -/* Define this if pushing a word on the stack - makes the stack pointer a smaller address. */ -#define STACK_GROWS_DOWNWARD - -/* Define this if the nominal address of the stack frame - is at the high-address end of the local variables; - that is, each additional local variable allocated - goes at a more negative offset in the frame. */ -#define FRAME_GROWS_DOWNWARD - -/* Offset within stack frame to start allocating local variables at. - If FRAME_GROWS_DOWNWARD, this is the offset to the END of the - first local allocated. Otherwise, it is the offset to the BEGINNING - of the first local allocated. */ -#define STARTING_FRAME_OFFSET 0 - -/* If we generate an insn to push BYTES bytes, - this says how many the stack pointer really advances by. - On 386 pushw decrements by exactly 2 no matter what the position was. - On the 386 there is no pushb; we use pushw instead, and this - has the effect of rounding up to 2. */ - -#define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & (-2)) - -/* Offset of first parameter from the argument pointer register value. */ -#define FIRST_PARM_OFFSET(FNDECL) 0 - -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. - - On the 80386, the RTD insn may be used to pop them if the number - of args is fixed, but if the number is variable then the caller - must pop them all. RTD can't be used for library calls now - because the library is compiled with the Unix compiler. - Use of RTD is a selectable option, since it is incompatible with - standard Unix calling sequences. If the option is not selected, - the caller must always pop the args. - - The attribute stdcall is equivalent to RTD on a per module basis. */ - -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \ - (i386_return_pops_args (FUNDECL, FUNTYPE, SIZE)) - -/* Define how to find the value returned by a function. - VALTYPE is the data type of the value (as a tree). - If the precise function being called is known, FUNC is its FUNCTION_DECL; - otherwise, FUNC is 0. */ -#define FUNCTION_VALUE(VALTYPE, FUNC) \ - gen_rtx (REG, TYPE_MODE (VALTYPE), \ - VALUE_REGNO (TYPE_MODE (VALTYPE))) - -/* Define how to find the value returned by a library function - assuming the value has mode MODE. */ - -#define LIBCALL_VALUE(MODE) \ - gen_rtx (REG, MODE, VALUE_REGNO (MODE)) - -/* Define the size of the result block used for communication between - untyped_call and untyped_return. The block contains a DImode value - followed by the block used by fnsave and frstor. */ - -#define APPLY_RESULT_SIZE (8+108) - -/* 1 if N is a possible register number for function argument passing. */ -#define FUNCTION_ARG_REGNO_P(N) ((N) >= 0 && (N) < REGPARM_MAX) - -/* Define a data type for recording info about an argument list - during the scan of that argument list. This data type should - hold all necessary information about the function itself - and about the args processed so far, enough to enable macros - such as FUNCTION_ARG to determine where the next arg should go. */ - -//typedef struct i386_args { -// int words; /* # words passed so far */ -// int nregs; /* # registers available for passing */ -// int regno; /* next available register number */ -//} CUMULATIVE_ARGS; - -/* Initialize a variable CUM of type CUMULATIVE_ARGS - for a call to a function whose data type is FNTYPE. - For a library call, FNTYPE is 0. */ - -#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ - (init_cumulative_args (&CUM, FNTYPE, LIBNAME)) - -/* Update the data in CUM to advance over an argument - of mode MODE and data type TYPE. - (TYPE is null for libcalls where that information may not be available.) */ - -#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ - (function_arg_advance (&CUM, MODE, TYPE, NAMED)) - -/* Define where to put the arguments to a function. - Value is zero to push the argument on the stack, - or a hard register in which to store the argument. - - MODE is the argument's machine mode. - TYPE is the data type of the argument (as a tree). - This is null for libcalls where that information may - not be available. - CUM is a variable of type CUMULATIVE_ARGS which gives info about - the preceding args and about the function being called. - NAMED is nonzero if this argument is a named parameter - (otherwise it is an extra parameter matching an ellipsis). */ - -#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ - (function_arg (&CUM, MODE, TYPE, NAMED)) - -/* For an arg passed partly in registers and partly in memory, - this is the number of registers used. - For args passed entirely in registers or entirely in memory, zero. */ - -#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ - (function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)) - -/* This macro generates the assembly code for function entry. - FILE is a stdio stream to output the code to. - SIZE is an int: how many units of temporary storage to allocate. - Refer to the array `regs_ever_live' to determine which registers - to save; `regs_ever_live[I]' is nonzero if register number I - is ever used in the function. This macro is responsible for - knowing which registers should not be saved even if used. */ - -#define FUNCTION_PROLOGUE(FILE, SIZE) \ - function_prologue (FILE, SIZE) - -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. */ - -#define FUNCTION_PROFILER(FILE, LABELNO) \ -{ \ - if (flag_pic) \ - { \ - fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \ - LPREFIX, (LABELNO)); \ - fprintf (FILE, "\tcall *_mcount@GOT(%%ebx)\n"); \ - } \ - else \ - { \ - fprintf (FILE, "\tmovl $%sP%d,%%edx\n", LPREFIX, (LABELNO)); \ - fprintf (FILE, "\tcall _mcount\n"); \ - } \ -} - -/* A C statement or compound statement to output to FILE some - assembler code to initialize basic-block profiling for the current - object module. This code should call the subroutine - `__bb_init_func' once per object module, passing it as its sole - argument the address of a block allocated in the object module. - - The name of the block is a local symbol made with this statement: - - ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0); - - Of course, since you are writing the definition of - `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you - can take a short cut in the definition of this macro and use the - name that you know will result. - - The first word of this block is a flag which will be nonzero if the - object module has already been initialized. So test this word - first, and do not call `__bb_init_func' if the flag is nonzero. */ - -#undef FUNCTION_BLOCK_PROFILER -#define FUNCTION_BLOCK_PROFILER(STREAM, LABELNO) \ -do \ - { \ - static int num_func = 0; \ - rtx xops[8]; \ - char block_table[80], false_label[80]; \ - \ - ASM_GENERATE_INTERNAL_LABEL (block_table, "LPBX", 0); \ - ASM_GENERATE_INTERNAL_LABEL (false_label, "LPBZ", num_func); \ - \ - xops[0] = const0_rtx; \ - xops[1] = gen_rtx (SYMBOL_REF, VOIDmode, block_table); \ - xops[2] = gen_rtx (MEM, Pmode, gen_rtx (SYMBOL_REF, VOIDmode, false_label)); \ - xops[3] = gen_rtx (MEM, Pmode, gen_rtx (SYMBOL_REF, VOIDmode, "__bb_init_func")); \ - xops[4] = gen_rtx (MEM, Pmode, xops[1]); \ - xops[5] = stack_pointer_rtx; \ - xops[6] = GEN_INT (4); \ - xops[7] = gen_rtx (REG, Pmode, 0); /* eax */ \ - \ - CONSTANT_POOL_ADDRESS_P (xops[1]) = TRUE; \ - CONSTANT_POOL_ADDRESS_P (xops[2]) = TRUE; \ - \ - output_asm_insn (AS2(cmp%L4,%0,%4), xops); \ - output_asm_insn (AS1(jne,%2), xops); \ - \ - if (!flag_pic) \ - output_asm_insn (AS1(push%L1,%1), xops); \ - else \ - { \ - output_asm_insn (AS2 (lea%L7,%a1,%7), xops); \ - output_asm_insn (AS1 (push%L7,%7), xops); \ - } \ - \ - output_asm_insn (AS1(call,%P3), xops); \ - output_asm_insn (AS2(add%L0,%6,%5), xops); \ - ASM_OUTPUT_INTERNAL_LABEL (STREAM, "LPBZ", num_func); \ - num_func++; \ - } \ -while (0) - - -/* A C statement or compound statement to increment the count - associated with the basic block number BLOCKNO. Basic blocks are - numbered separately from zero within each compilation. The count - associated with block number BLOCKNO is at index BLOCKNO in a - vector of words; the name of this array is a local symbol made - with this statement: - - ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 2); - - Of course, since you are writing the definition of - `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you - can take a short cut in the definition of this macro and use the - name that you know will result. */ - -#define BLOCK_PROFILER(STREAM, BLOCKNO) \ -do \ - { \ - rtx xops[1], cnt_rtx; \ - char counts[80]; \ - \ - ASM_GENERATE_INTERNAL_LABEL (counts, "LPBX", 2); \ - cnt_rtx = gen_rtx (SYMBOL_REF, VOIDmode, counts); \ - SYMBOL_REF_FLAG (cnt_rtx) = TRUE; \ - \ - if (BLOCKNO) \ - cnt_rtx = plus_constant (cnt_rtx, (BLOCKNO)*4); \ - \ - if (flag_pic) \ - cnt_rtx = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, cnt_rtx); \ - \ - xops[0] = gen_rtx (MEM, SImode, cnt_rtx); \ - output_asm_insn (AS1(inc%L0,%0), xops); \ - } \ -while (0) - -/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, - the stack pointer does not matter. The value is tested only in - functions that have frame pointers. - No definition is equivalent to always zero. */ -/* Note on the 386 it might be more efficient not to define this since - we have to restore it ourselves from the frame pointer, in order to - use pop */ - -#define EXIT_IGNORE_STACK 1 - -/* This macro generates the assembly code for function exit, - on machines that need it. If FUNCTION_EPILOGUE is not defined - then individual return instructions are generated for each - return statement. Args are same as for FUNCTION_PROLOGUE. - - The function epilogue should not depend on the current stack pointer! - It should use the frame pointer only. This is mandatory because - of alloca; we also take advantage of it to omit stack adjustments - before returning. - - If the last non-note insn in the function is a BARRIER, then there - is no need to emit a function prologue, because control does not fall - off the end. This happens if the function ends in an "exit" call, or - if a `return' insn is emitted directly into the function. */ - -#define FUNCTION_EPILOGUE(FILE, SIZE) \ -do { \ - rtx last = get_last_insn (); \ - if (last && GET_CODE (last) == NOTE) \ - last = prev_nonnote_insn (last); \ - if (! last || GET_CODE (last) != BARRIER) \ - function_epilogue (FILE, SIZE); \ -} while (0) - -/* Output assembler code for a block containing the constant parts - of a trampoline, leaving space for the variable parts. */ - -/* On the 386, the trampoline contains three instructions: - mov #STATIC,ecx - mov #FUNCTION,eax - jmp @eax */ -#define TRAMPOLINE_TEMPLATE(FILE) \ -{ \ - ASM_OUTPUT_CHAR (FILE, GEN_INT (0xb9)); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_CHAR (FILE, GEN_INT (0xb8)); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_CHAR (FILE, GEN_INT (0xff)); \ - ASM_OUTPUT_CHAR (FILE, GEN_INT (0xe0)); \ -} - -/* Length in units of the trampoline for entering a nested function. */ - -#define TRAMPOLINE_SIZE 12 - -/* Emit RTL insns to initialize the variable parts of a trampoline. - FNADDR is an RTX for the address of the function's pure code. - CXT is an RTX for the static chain value for the function. */ - -#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ -{ \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 1)), CXT); \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 6)), FNADDR); \ -} - -/* Definitions for register eliminations. - - This is an array of structures. Each structure initializes one pair - of eliminable registers. The "from" register number is given first, - followed by "to". Eliminations of the same "from" register are listed - in order of preference. - - We have two registers that can be eliminated on the i386. First, the - frame pointer register can often be eliminated in favor of the stack - pointer register. Secondly, the argument pointer register can always be - eliminated; it is replaced with either the stack or frame pointer. */ - -#define ELIMINABLE_REGS \ -{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ - { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}} - -/* Given FROM and TO register numbers, say whether this elimination is allowed. - Frame pointer elimination is automatically handled. - - For the i386, if frame pointer elimination is being done, we would like to - convert ap into sp, not fp. - - All other eliminations are valid. */ - -#define CAN_ELIMINATE(FROM, TO) \ - ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \ - ? ! frame_pointer_needed \ - : 1) - -/* Define the offset between two registers, one to be eliminated, and the other - its replacement, at the start of a routine. */ - -#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ -{ \ - if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM) \ - (OFFSET) = 8; /* Skip saved PC and previous frame pointer */ \ - else \ - { \ - int regno; \ - int offset = 0; \ - \ - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \ - if ((regs_ever_live[regno] && ! call_used_regs[regno]) \ - || (current_function_uses_pic_offset_table \ - && regno == PIC_OFFSET_TABLE_REGNUM)) \ - offset += 4; \ - \ - (OFFSET) = offset + get_frame_size (); \ - \ - if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ - (OFFSET) += 4; /* Skip saved PC */ \ - } \ -} - -/* Addressing modes, and classification of registers for them. */ - -/* #define HAVE_POST_INCREMENT */ -/* #define HAVE_POST_DECREMENT */ - -/* #define HAVE_PRE_DECREMENT */ -/* #define HAVE_PRE_INCREMENT */ - -/* Macros to check register numbers against specific register classes. */ - -/* These assume that REGNO is a hard or pseudo reg number. - They give nonzero only if REGNO is a hard reg of the suitable class - or a pseudo reg currently allocated to a suitable hard reg. - Since they use reg_renumber, they are safe only once reg_renumber - has been allocated, which happens in local-alloc.c. */ - -#define REGNO_OK_FOR_INDEX_P(REGNO) \ - ((REGNO) < STACK_POINTER_REGNUM \ - || (unsigned) reg_renumber[REGNO] < STACK_POINTER_REGNUM) - -#define REGNO_OK_FOR_BASE_P(REGNO) \ - ((REGNO) <= STACK_POINTER_REGNUM \ - || (REGNO) == ARG_POINTER_REGNUM \ - || (unsigned) reg_renumber[REGNO] <= STACK_POINTER_REGNUM) - -#define REGNO_OK_FOR_SIREG_P(REGNO) ((REGNO) == 4 || reg_renumber[REGNO] == 4) -#define REGNO_OK_FOR_DIREG_P(REGNO) ((REGNO) == 5 || reg_renumber[REGNO] == 5) - -/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx - and check its validity for a certain class. - We have two alternate definitions for each of them. - The usual definition accepts all pseudo regs; the other rejects - them unless they have been allocated suitable hard regs. - The symbol REG_OK_STRICT causes the latter definition to be used. - - Most source files want to accept pseudo regs in the hope that - they will get allocated to the class that the insn wants them to be in. - Source files for reload pass need to be strict. - After reload, it makes no difference, since pseudo regs have - been eliminated by then. */ - - -/* Non strict versions, pseudos are ok */ -#define REG_OK_FOR_INDEX_NONSTRICT_P(X) \ - (REGNO (X) < STACK_POINTER_REGNUM \ - || REGNO (X) >= FIRST_PSEUDO_REGISTER) - -#define REG_OK_FOR_BASE_NONSTRICT_P(X) \ - (REGNO (X) <= STACK_POINTER_REGNUM \ - || REGNO (X) == ARG_POINTER_REGNUM \ - || REGNO (X) >= FIRST_PSEUDO_REGISTER) - -#define REG_OK_FOR_STRREG_NONSTRICT_P(X) \ - (REGNO (X) == 4 || REGNO (X) == 5 || REGNO (X) >= FIRST_PSEUDO_REGISTER) - -/* Strict versions, hard registers only */ -#define REG_OK_FOR_INDEX_STRICT_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) -#define REG_OK_FOR_BASE_STRICT_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) -#define REG_OK_FOR_STRREG_STRICT_P(X) \ - (REGNO_OK_FOR_DIREG_P (REGNO (X)) || REGNO_OK_FOR_SIREG_P (REGNO (X))) - -#ifndef REG_OK_STRICT -#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_INDEX_NONSTRICT_P(X) -#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_NONSTRICT_P(X) -#define REG_OK_FOR_STRREG_P(X) REG_OK_FOR_STRREG_NONSTRICT_P(X) - -#else -#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_INDEX_STRICT_P(X) -#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_STRICT_P(X) -#define REG_OK_FOR_STRREG_P(X) REG_OK_FOR_STRREG_STRICT_P(X) -#endif - -/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression - that is a valid memory address for an instruction. - The MODE argument is the machine mode for the MEM expression - that wants to use this address. - - The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS, - except for CONSTANT_ADDRESS_P which is usually machine-independent. - - See legitimize_pic_address in i386.c for details as to what - constitutes a legitimate address when -fpic is used. */ - -#define MAX_REGS_PER_ADDRESS 2 - -#define CONSTANT_ADDRESS_P(X) \ - (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ - || GET_CODE (X) == HIGH) - -/* Nonzero if the constant value X is a legitimate general operand. - It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ - -#define LEGITIMATE_CONSTANT_P(X) 1 - -#ifdef REG_OK_STRICT -#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ -{ \ - if (legitimate_address_p (MODE, X, 1)) \ - goto ADDR; \ -} - -#else -#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ -{ \ - if (legitimate_address_p (MODE, X, 0)) \ - goto ADDR; \ -} - -#endif - -/* Try machine-dependent ways of modifying an illegitimate address - to be legitimate. If we find one, return the new, valid address. - This macro is used in only one place: `memory_address' in explow.c. - - OLDX is the address as it was before break_out_memory_refs was called. - In some cases it is useful to look at this to decide what needs to be done. - - MODE and WIN are passed so that this macro can use - GO_IF_LEGITIMATE_ADDRESS. - - It is always safe for this macro to do nothing. It exists to recognize - opportunities to optimize the output. - - For the 80386, we handle X+REG by loading X into a register R and - using R+REG. R will go in a general reg and indexing will be used. - However, if REG is a broken-out memory address or multiplication, - nothing needs to be done because REG can certainly go in a general reg. - - When -fpic is used, special handling is needed for symbolic references. - See comments by legitimize_pic_address in i386.c for details. */ - -#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ -{ \ - rtx orig_x = (X); \ - (X) = legitimize_address (X, OLDX, MODE); \ - if (memory_address_p (MODE, X)) \ - goto WIN; \ -} - -/* Nonzero if the constant value X is a legitimate general operand - when generating PIC code. It is given that flag_pic is on and - that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ - -#define LEGITIMATE_PIC_OPERAND_P(X) \ - (! SYMBOLIC_CONST (X) \ - || (GET_CODE (X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (X))) - -#define SYMBOLIC_CONST(X) \ -(GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == LABEL_REF \ - || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X))) - -/* Go to LABEL if ADDR (a legitimate address expression) - has an effect that depends on the machine mode it is used for. - On the 80386, only postdecrement and postincrement address depend thus - (the amount of decrement or increment being the length of the operand). */ -#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \ - if (GET_CODE (ADDR) == POST_INC || GET_CODE (ADDR) == POST_DEC) goto LABEL - -/* Define this macro if references to a symbol must be treated - differently depending on something about the variable or - function named by the symbol (such as what section it is in). - - On i386, if using PIC, mark a SYMBOL_REF for a non-global symbol - so that we may access it directly in the GOT. */ - -#define ENCODE_SECTION_INFO(DECL) \ -do \ - { \ - if (flag_pic) \ - { \ - rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ - ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \ - SYMBOL_REF_FLAG (XEXP (rtl, 0)) \ - = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ - || ! TREE_PUBLIC (DECL)); \ - } \ - } \ -while (0) - -/* Initialize data used by insn expanders. This is called from - init_emit, once for each function, before code is generated. - For 386, clear stack slot assignments remembered from previous - functions. */ - -#define INIT_EXPANDERS clear_386_stack_locals () - -/* The `FINALIZE_PIC' macro serves as a hook to emit these special - codes once the function is being compiled into assembly code, but - not before. (It is not done before, because in the case of - compiling an inline function, it would lead to multiple PIC - prologues being included in functions which used inline functions - and were compiled to assembly language.) */ - -#define FINALIZE_PIC \ -do \ - { \ - extern int current_function_uses_pic_offset_table; \ - \ - current_function_uses_pic_offset_table |= profile_flag | profile_block_flag; \ - } \ -while (0) - - -/* If defined, a C expression whose value is nonzero if IDENTIFIER - with arguments ARGS is a valid machine specific attribute for DECL. - The attributes in ATTRIBUTES have previously been assigned to DECL. */ - -#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, NAME, ARGS) \ - (i386_valid_decl_attribute_p (DECL, ATTRIBUTES, NAME, ARGS)) - -/* If defined, a C expression whose value is nonzero if IDENTIFIER - with arguments ARGS is a valid machine specific attribute for TYPE. - The attributes in ATTRIBUTES have previously been assigned to TYPE. */ - -#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, NAME, ARGS) \ - (i386_valid_type_attribute_p (TYPE, ATTRIBUTES, NAME, ARGS)) - -/* If defined, a C expression whose value is zero if the attributes on - TYPE1 and TYPE2 are incompatible, one if they are compatible, and - two if they are nearly compatible (which causes a warning to be - generated). */ - -#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \ - (i386_comp_type_attributes (TYPE1, TYPE2)) - -/* If defined, a C statement that assigns default attributes to newly - defined TYPE. */ - -/* #define SET_DEFAULT_TYPE_ATTRIBUTES (TYPE) */ - -/* Max number of args passed in registers. If this is more than 3, we will - have problems with ebx (register #4), since it is a caller save register and - is also used as the pic register in ELF. So for now, don't allow more than - 3 registers to be passed in registers. */ - -#define REGPARM_MAX 3 - - -/* Specify the machine mode that this machine uses - for the index in the tablejump instruction. */ -#define CASE_VECTOR_MODE Pmode - -/* Define this if the tablejump instruction expects the table - to contain offsets from the address of the table. - Do not define this if the table should contain absolute addresses. */ -/* #define CASE_VECTOR_PC_RELATIVE */ - -/* Specify the tree operation to be used to convert reals to integers. - This should be changed to take advantage of fist --wfs ?? - */ -#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR - -/* This is the kind of divide that is easiest to do in the general case. */ -#define EASY_DIV_EXPR TRUNC_DIV_EXPR - -/* Define this as 1 if `char' should by default be signed; else as 0. */ -#define DEFAULT_SIGNED_CHAR 1 - -/* Max number of bytes we can move from memory to memory - in one reasonably fast instruction. */ -#define MOVE_MAX 4 - -/* MOVE_RATIO is the number of move instructions that is better than a - block move. Make this large on i386, since the block move is very - inefficient with small blocks, and the hard register needs of the - block move require much reload work. */ -#define MOVE_RATIO 5 - -/* Define this if zero-extension is slow (more than one real instruction). */ -/* #define SLOW_ZERO_EXTEND */ - -/* Nonzero if access to memory by bytes is slow and undesirable. */ -#define SLOW_BYTE_ACCESS 0 - -/* Define if shifts truncate the shift count - which implies one can omit a sign-extension or zero-extension - of a shift count. */ -/* One i386, shifts do truncate the count. But bit opcodes don't. */ - -/* #define SHIFT_COUNT_TRUNCATED */ - -/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits - is done just by pretending it is already truncated. */ -#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 - -/* We assume that the store-condition-codes instructions store 0 for false - and some other value for true. This is the value stored for true. */ - -#define STORE_FLAG_VALUE 1 - -/* When a prototype says `char' or `short', really pass an `int'. - (The 386 can't easily push less than an int.) */ - -#define PROMOTE_PROTOTYPES - -/* Specify the machine mode that pointers have. - After generation of rtl, the compiler makes no further distinction - between pointers and any other objects of this machine mode. */ -#define Pmode SImode - -/* A function address in a call instruction - is a byte address (for indexing purposes) - so give the MEM rtx a byte's mode. */ -#define FUNCTION_MODE QImode - -/* Define this if addresses of constant functions - shouldn't be put through pseudo regs where they can be cse'd. - Desirable on the 386 because a CALL with a constant address is - not much slower than one with a register address. On a 486, - it is faster to call with a constant address than indirect. */ -#define NO_FUNCTION_CSE - -/* Provide the costs of a rtl expression. This is in the body of a - switch on CODE. */ - -#define RTX_COSTS(X,CODE,OUTER_CODE) \ - case MULT: \ - return COSTS_N_INSNS (20); \ - case DIV: \ - case UDIV: \ - case MOD: \ - case UMOD: \ - return COSTS_N_INSNS (20); \ - case ASHIFTRT: \ - case LSHIFTRT: \ - case ASHIFT: \ - return (4 + rtx_cost (XEXP (X, 0), OUTER_CODE) \ - + rtx_cost (XEXP (X, 1), OUTER_CODE)); \ - case PLUS: \ - if (GET_CODE (XEXP (X, 0)) == MULT \ - && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \ - && (INTVAL (XEXP (XEXP (X, 0), 1)) == 2 \ - || INTVAL (XEXP (XEXP (X, 0), 1)) == 4 \ - || INTVAL (XEXP (XEXP (X, 0), 1)) == 8)) \ - return (2 + rtx_cost (XEXP (XEXP (X, 0), 0), OUTER_CODE) \ - + rtx_cost (XEXP (X, 1), OUTER_CODE)); \ - break; - - -/* Compute the cost of computing a constant rtl expression RTX - whose rtx-code is CODE. The body of this macro is a portion - of a switch statement. If the code is computed here, - return it with a return statement. Otherwise, break from the switch. */ - -#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ - case CONST_INT: \ - case CONST: \ - case LABEL_REF: \ - case SYMBOL_REF: \ - return flag_pic && SYMBOLIC_CONST (RTX) ? 2 : 0; \ - case CONST_DOUBLE: \ - { \ - int code; \ - if (GET_MODE (RTX) == VOIDmode) \ - return 2; \ - code = standard_80387_constant_p (RTX); \ - return code == 1 ? 0 : \ - code == 2 ? 1 : \ - 2; \ - } - -/* Compute the cost of an address. This is meant to approximate the size - and/or execution delay of an insn using that address. If the cost is - approximated by the RTL complexity, including CONST_COSTS above, as - is usually the case for CISC machines, this macro should not be defined. - For aggressively RISCy machines, only one insn format is allowed, so - this macro should be a constant. The value of this macro only matters - for valid addresses. - - For i386, it is better to use a complex address than let gcc copy - the address into a reg and make a new pseudo. But not if the address - requires to two regs - that would mean more pseudos with longer - lifetimes. */ - -#define ADDRESS_COST(RTX) \ - ((CONSTANT_P (RTX) \ - || (GET_CODE (RTX) == PLUS && CONSTANT_P (XEXP (RTX, 1)) \ - && REG_P (XEXP (RTX, 0)))) ? 0 \ - : REG_P (RTX) ? 1 \ - : 2) - -/* Add any extra modes needed to represent the condition code. - - For the i386, we need separate modes when floating-point equality - comparisons are being done. */ - -#define EXTRA_CC_MODES CCFPEQmode - -/* Define the names for the modes specified above. */ -#define EXTRA_CC_NAMES "CCFPEQ" - -/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, - return the mode to be used for the comparison. - - For floating-point equality comparisons, CCFPEQmode should be used. - VOIDmode should be used in all other cases. */ - -#define SELECT_CC_MODE(OP,X,Y) \ - (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ - && ((OP) == EQ || (OP) == NE) ? CCFPEQmode : VOIDmode) - -/* Define the information needed to generate branch and scc insns. This is - stored from the compare operation. Note that we can't use "rtx" here - since it hasn't been defined! */ - -extern struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)(); - -/* Tell final.c how to eliminate redundant test instructions. */ - -/* Here we define machine-dependent flags and fields in cc_status - (see `conditions.h'). */ - -/* Set if the cc value is actually in the 80387, so a floating point - conditional branch must be output. */ -#define CC_IN_80387 04000 - -/* Set if the CC value was stored in a nonstandard way, so that - the state of equality is indicated by zero in the carry bit. */ -#define CC_Z_IN_NOT_C 010000 - -/* Store in cc_status the expressions - that the condition codes will describe - after execution of an instruction whose pattern is EXP. - Do not alter them if the instruction would not alter the cc's. */ - -#define NOTICE_UPDATE_CC(EXP, INSN) \ - notice_update_cc((EXP)) - -/* Output a signed jump insn. Use template NORMAL ordinarily, or - FLOAT following a floating point comparison. - Use NO_OV following an arithmetic insn that set the cc's - before a test insn that was deleted. - NO_OV may be zero, meaning final should reinsert the test insn - because the jump cannot be handled properly without it. */ - -#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \ -{ \ - if (cc_prev_status.flags & CC_IN_80387) \ - return FLOAT; \ - if (cc_prev_status.flags & CC_NO_OVERFLOW) \ - return NO_OV; \ - return NORMAL; \ -} - -/* Control the assembler format that we output, to the extent - this does not vary between assemblers. */ - -/* How to refer to registers in assembler output. - This sequence is indexed by compiler's hard-register-number (see above). */ - -/* In order to refer to the first 8 regs as 32 bit regs prefix an "e" - For non floating point regs, the following are the HImode names. - - For float regs, the stack top is sometimes referred to as "%st(0)" - instead of just "%st". PRINT_REG handles this with the "y" code. */ - -#define HI_REGISTER_NAMES \ -{"ax","dx","cx","bx","si","di","bp","sp", \ - "st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)","" } - -#define REGISTER_NAMES HI_REGISTER_NAMES - -/* Table of additional register names to use in user input. */ - -#define ADDITIONAL_REGISTER_NAMES \ -{ "eax", 0, "edx", 1, "ecx", 2, "ebx", 3, \ - "esi", 4, "edi", 5, "ebp", 6, "esp", 7, \ - "al", 0, "dl", 1, "cl", 2, "bl", 3, \ - "ah", 0, "dh", 1, "ch", 2, "bh", 3 } - -/* Note we are omitting these since currently I don't know how -to get gcc to use these, since they want the same but different -number as al, and ax. -*/ - -/* note the last four are not really qi_registers, but - the md will have to never output movb into one of them - only a movw . There is no movb into the last four regs */ - -#define QI_REGISTER_NAMES \ -{"al", "dl", "cl", "bl", "si", "di", "bp", "sp",} - -/* These parallel the array above, and can be used to access bits 8:15 - of regs 0 through 3. */ - -#define QI_HIGH_REGISTER_NAMES \ -{"ah", "dh", "ch", "bh", } - -/* How to renumber registers for dbx and gdb. */ - -/* {0,2,1,3,6,7,4,5,12,13,14,15,16,17} */ -#define DBX_REGISTER_NUMBER(n) \ -((n) == 0 ? 0 : \ - (n) == 1 ? 2 : \ - (n) == 2 ? 1 : \ - (n) == 3 ? 3 : \ - (n) == 4 ? 6 : \ - (n) == 5 ? 7 : \ - (n) == 6 ? 4 : \ - (n) == 7 ? 5 : \ - (n) + 4) - -/* This is how to output the definition of a user-level label named NAME, - such as the label on a static function or variable NAME. */ - -#define ASM_OUTPUT_LABEL(FILE,NAME) \ - (assemble_name (FILE, NAME), fputs (":\n", FILE)) - -/* This is how to output an assembler line defining a `double' constant. */ - -#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ -do { long l[2]; \ - REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \ - if (sizeof (int) == sizeof (long)) \ - fprintf (FILE, "%s 0x%x,0x%x\n", ASM_LONG, l[0], l[1]); \ - else \ - fprintf (FILE, "%s 0x%lx,0x%lx\n", ASM_LONG, l[0], l[1]); \ - } while (0) - -/* This is how to output a `long double' extended real constant. */ - -#undef ASM_OUTPUT_LONG_DOUBLE -#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ -do { long l[3]; \ - REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \ - if (sizeof (int) == sizeof (long)) \ - fprintf (FILE, "%s 0x%x,0x%x,0x%x\n", ASM_LONG, l[0], l[1], l[2]); \ - else \ - fprintf (FILE, "%s 0x%lx,0x%lx,0x%lx\n", ASM_LONG, l[0], l[1], l[2]); \ - } while (0) - -/* This is how to output an assembler line defining a `float' constant. */ - -#define ASM_OUTPUT_FLOAT(FILE,VALUE) \ -do { long l; \ - REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ - if (sizeof (int) == sizeof (long)) \ - fprintf ((FILE), "%s 0x%x\n", ASM_LONG, l); \ - else \ - fprintf ((FILE), "%s 0x%lx\n", ASM_LONG, l); \ - } while (0) - -/* Store in OUTPUT a string (made with alloca) containing - an assembler-name for a local static variable named NAME. - LABELNO is an integer which is different for each call. */ - -#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ -( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \ - sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO))) - - - -/* This is how to output an assembler line defining an `int' constant. */ - -#define ASM_OUTPUT_INT(FILE,VALUE) \ -( fprintf (FILE, "%s ", ASM_LONG), \ - output_addr_const (FILE,(VALUE)), \ - putc('\n',FILE)) - -/* Likewise for `char' and `short' constants. */ -/* is this supposed to do align too?? */ - -#define ASM_OUTPUT_SHORT(FILE,VALUE) \ -( fprintf (FILE, "%s ", ASM_SHORT), \ - output_addr_const (FILE,(VALUE)), \ - putc('\n',FILE)) - -/* -#define ASM_OUTPUT_SHORT(FILE,VALUE) \ -( fprintf (FILE, "%s ", ASM_BYTE_OP), \ - output_addr_const (FILE,(VALUE)), \ - fputs (",", FILE), \ - output_addr_const (FILE,(VALUE)), \ - fputs (" >> 8\n",FILE)) -*/ - - -#define ASM_OUTPUT_CHAR(FILE,VALUE) \ -( fprintf (FILE, "%s ", ASM_BYTE_OP), \ - output_addr_const (FILE, (VALUE)), \ - putc ('\n', FILE)) - -/* This is how to output an assembler line for a numeric constant byte. */ - -#define ASM_OUTPUT_BYTE(FILE,VALUE) \ - fprintf ((FILE), "%s 0x%x\n", ASM_BYTE_OP, (VALUE)) - -/* This is how to output an insn to push a register on the stack. - It need not be very fast code. */ - -#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ - fprintf (FILE, "\tpushl e%s\n", reg_names[REGNO]) - -/* This is how to output an insn to pop a register from the stack. - It need not be very fast code. */ - -#define ASM_OUTPUT_REG_POP(FILE,REGNO) \ - fprintf (FILE, "\tpopl e%s\n", reg_names[REGNO]) - -/* This is how to output an element of a case-vector that is absolute. - */ - -#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ - fprintf (FILE, "%s %s%d\n", ASM_LONG, LPREFIX, VALUE) - -/* This is how to output an element of a case-vector that is relative. - We don't use these on the 386 yet, because the ATT assembler can't do - forward reference the differences. - */ - -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ - fprintf (FILE, "\t.word %s%d-%s%d\n",LPREFIX, VALUE,LPREFIX, REL) - -/* Define the parentheses used to group arithmetic operations - in assembler code. */ - -#define ASM_OPEN_PAREN "" -#define ASM_CLOSE_PAREN "" - -/* Define results of standard character escape sequences. */ -#define TARGET_BELL 007 -#define TARGET_BS 010 -#define TARGET_TAB 011 -#define TARGET_NEWLINE 012 -#define TARGET_VT 013 -#define TARGET_FF 014 -#define TARGET_CR 015 - -/* Print operand X (an rtx) in assembler syntax to file FILE. - CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified. - The CODE z takes the size of operand from the following digit, and - outputs b,w,or l respectively. - - On the 80386, we use several such letters: - f -- float insn (print a CONST_DOUBLE as a float rather than in hex). - L,W,B,Q,S,T -- print the opcode suffix for specified size of operand. - R -- print the prefix for register names. - z -- print the opcode suffix for the size of the current operand. - * -- print a star (in certain assembler syntax) - w -- print the operand as if it's a "word" (HImode) even if it isn't. - b -- print the operand as if it's a byte (QImode) even if it isn't. - c -- don't print special prefixes before constant operands. */ - -#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ - ((CODE) == '*') - -/* Print the name of a register based on its machine mode and number. - If CODE is 'w', pretend the mode is HImode. - If CODE is 'b', pretend the mode is QImode. - If CODE is 'k', pretend the mode is SImode. - If CODE is 'h', pretend the reg is the `high' byte register. - If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op. */ - -extern char *hi_reg_name[]; -extern char *qi_reg_name[]; -extern char *qi_high_reg_name[]; - -#define PRINT_REG(X, CODE, FILE) \ - do { if (REGNO (X) == ARG_POINTER_REGNUM) \ - abort (); \ - fprintf (FILE, "%s", RP); \ - switch ((CODE == 'w' ? 2 \ - : CODE == 'b' ? 1 \ - : CODE == 'k' ? 4 \ - : CODE == 'y' ? 3 \ - : CODE == 'h' ? 0 \ - : GET_MODE_SIZE (GET_MODE (X)))) \ - { \ - case 3: \ - if (STACK_TOP_P (X)) \ - { \ - fputs ("st(0)", FILE); \ - break; \ - } \ - case 4: \ - case 8: \ - case 12: \ - if (! FP_REG_P (X)) fputs ("e", FILE); \ - case 2: \ - fputs (hi_reg_name[REGNO (X)], FILE); \ - break; \ - case 1: \ - fputs (qi_reg_name[REGNO (X)], FILE); \ - break; \ - case 0: \ - fputs (qi_high_reg_name[REGNO (X)], FILE); \ - break; \ - } \ - } while (0) - -#define PRINT_OPERAND(FILE, X, CODE) \ - print_operand (FILE, X, CODE) - -#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ - print_operand_address (FILE, ADDR) - -/* Print the name of a register for based on its machine mode and number. - This macro is used to print debugging output. - This macro is different from PRINT_REG in that it may be used in - programs that are not linked with aux-output.o. */ - -#define DEBUG_PRINT_REG(X, CODE, FILE) \ - do { static char *hi_name[] = HI_REGISTER_NAMES; \ - static char *qi_name[] = QI_REGISTER_NAMES; \ - fprintf (FILE, "%d %s", REGNO (X), RP); \ - if (REGNO (X) == ARG_POINTER_REGNUM) \ - { fputs ("argp", FILE); break; } \ - if (STACK_TOP_P (X)) \ - { fputs ("st(0)", FILE); break; } \ - if (FP_REG_P (X)) \ - { fputs (hi_name[REGNO(X)], FILE); break; } \ - switch (GET_MODE_SIZE (GET_MODE (X))) \ - { \ - default: \ - fputs ("e", FILE); \ - case 2: \ - fputs (hi_name[REGNO (X)], FILE); \ - break; \ - case 1: \ - fputs (qi_name[REGNO (X)], FILE); \ - break; \ - } \ - } while (0) - -/* Output the prefix for an immediate operand, or for an offset operand. */ -#define PRINT_IMMED_PREFIX(FILE) fputs (IP, (FILE)) -#define PRINT_OFFSET_PREFIX(FILE) fputs (IP, (FILE)) - -/* Routines in libgcc that return floats must return them in an fp reg, - just as other functions do which return such values. - These macros make that happen. */ - -#define FLOAT_VALUE_TYPE float -#define INTIFY(FLOATVAL) FLOATVAL - -/* Nonzero if INSN magically clobbers register REGNO. */ - -/* #define INSN_CLOBBERS_REGNO_P(INSN, REGNO) \ - (FP_REGNO_P (REGNO) \ - && (GET_CODE (INSN) == JUMP_INSN || GET_CODE (INSN) == BARRIER)) -*/ - -/* a letter which is not needed by the normal asm syntax, which - we can use for operand syntax in the extended asm */ - -#define ASM_OPERAND_LETTER '#' - -#define RET return "" -#define AT_SP(mode) (gen_rtx (MEM, (mode), stack_pointer_rtx)) - -/* Functions in i386.c */ -extern void override_options (); -extern void order_regs_for_local_alloc (); -extern int i386_valid_decl_attribute_p (); -extern int i386_valid_type_attribute_p (); -extern int i386_return_pops_args (); -extern int i386_comp_type_attributes (); -extern void init_cumulative_args (); -extern void function_arg_advance (); -extern struct rtx_def *function_arg (); -extern int function_arg_partial_nregs (); -extern void output_op_from_reg (); -extern void output_to_reg (); -extern char *singlemove_string (); -extern char *output_move_double (); -extern char *output_move_memory (); -extern char *output_move_pushmem (); -extern int standard_80387_constant_p (); -extern char *output_move_const_single (); -extern int symbolic_operand (); -extern int call_insn_operand (); -extern int expander_call_insn_operand (); -extern int symbolic_reference_mentioned_p (); -extern void emit_pic_move (); -extern void function_prologue (); -extern int simple_386_epilogue (); -extern void function_epilogue (); -extern int legitimate_address_p (); -extern struct rtx_def *legitimize_pic_address (); -extern struct rtx_def *legitimize_address (); -extern void print_operand (); -extern void print_operand_address (); -extern void notice_update_cc (); -extern void split_di (); -extern int binary_387_op (); -extern int shift_op (); -extern int VOIDmode_compare_op (); -extern char *output_387_binary_op (); -extern char *output_fix_trunc (); -extern char *output_float_compare (); -extern char *output_fp_cc0_set (); -extern void save_386_machine_status (); -extern void restore_386_machine_status (); -extern void clear_386_stack_locals (); -extern struct rtx_def *assign_386_stack_local (); - -/* Variables in i386.c */ -extern char *i386_reg_alloc_order; /* register allocation order */ -extern char *i386_regparm_string; /* # registers to use to pass args */ -extern char *i386_align_loops_string; /* power of two alignment for loops */ -extern char *i386_align_jumps_string; /* power of two alignment for non-loop jumps */ -extern char *i386_align_funcs_string; /* power of two alignment for functions */ -extern int i386_regparm; /* i386_regparm_string as a number */ -extern int i386_align_loops; /* power of two alignment for loops */ -extern int i386_align_jumps; /* power of two alignment for non-loop jumps */ -extern int i386_align_funcs; /* power of two alignment for functions */ -extern char *hi_reg_name[]; /* names for 16 bit regs */ -extern char *qi_reg_name[]; /* names for 8 bit regs (low) */ -extern char *qi_high_reg_name[]; /* names for 8 bit regs (high) */ -extern enum reg_class regclass_map[]; /* smalled class containing REGNO */ -extern struct rtx_def *i386_compare_op0; /* operand 0 for comparisons */ -extern struct rtx_def *i386_compare_op1; /* operand 1 for comparisons */ - -/* External variables used */ -extern int optimize; /* optimization level */ -extern int obey_regdecls; /* TRUE if stupid register allocation */ - -/* External functions used */ -extern struct rtx_def *force_operand (); - -/* -Local variables: -version-control: t -End: -*/ diff --git a/support/cpp/i386/i386.md b/support/cpp/i386/i386.md deleted file mode 100644 index ff011963..00000000 --- a/support/cpp/i386/i386.md +++ /dev/null @@ -1,5775 +0,0 @@ -;; GCC machine description for Intel X86. -;; Copyright (C) 1988, 1994, 1995 Free Software Foundation, Inc. -;; Mostly by William Schelter. - -;; This file is part of GNU CC. - -;; GNU CC is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU CC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU CC; see the file COPYING. If not, write to -;; the Free Software Foundation, 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - - -;; The original PO technology requires these to be ordered by speed, -;; so that assigner will pick the fastest. - -;; See file "rtl.def" for documentation on define_insn, match_*, et. al. - -;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code -;; updates for most instructions. - -;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register -;; constraint letters. - -;; the special asm out single letter directives following a '%' are: -;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of -;; operands[1]. -;; 'L' Print the opcode suffix for a 32-bit integer opcode. -;; 'W' Print the opcode suffix for a 16-bit integer opcode. -;; 'B' Print the opcode suffix for an 8-bit integer opcode. -;; 'S' Print the opcode suffix for a 32-bit float opcode. -;; 'Q' Print the opcode suffix for a 64-bit float opcode. -;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode. -;; 'J' Print the appropriate jump operand. - -;; 'b' Print the QImode name of the register for the indicated operand. -;; %b0 would print %al if operands[0] is reg 0. -;; 'w' Likewise, print the HImode name of the register. -;; 'k' Likewise, print the SImode name of the register. -;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh. -;; 'y' Print "st(0)" instead of "st" as a register. - -;; UNSPEC usage: -;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode. -;; operand 0 is the memory address to scan. -;; operand 1 is a register containing the value to scan for. The mode -;; of the scas opcode will be the same as the mode of this operand. -;; operand 2 is the known alignment of operand 0. -;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT. -;; operand 0 is the argument for `sin'. -;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT. -;; operand 0 is the argument for `cos'. - -;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM". -;; But restricting MEM here would mean that gcc could not remove a redundant -;; test in cases like "incl MEM / je TARGET". -;; -;; We don't want to allow a constant operand for test insns because -;; (set (cc0) (const_int foo)) has no mode information. Such insns will -;; be folded while optimizing anyway. - -;; All test insns have expanders that save the operands away without -;; actually generating RTL. The bCOND or sCOND (emitted immediately -;; after the tstM or cmp) will actually emit the tstM or cmpM. - -(define_insn "tstsi_1" - [(set (cc0) - (match_operand:SI 0 "nonimmediate_operand" "rm"))] - "" - "* -{ - if (REG_P (operands[0])) - return AS2 (test%L0,%0,%0); - - operands[1] = const0_rtx; - return AS2 (cmp%L0,%1,%0); -}") - -(define_expand "tstsi" - [(set (cc0) - (match_operand:SI 0 "nonimmediate_operand" ""))] - "" - " -{ - i386_compare_gen = gen_tstsi_1; - i386_compare_op0 = operands[0]; - DONE; -}") - -(define_insn "tsthi_1" - [(set (cc0) - (match_operand:HI 0 "nonimmediate_operand" "rm"))] - "" - "* -{ - if (REG_P (operands[0])) - return AS2 (test%W0,%0,%0); - - operands[1] = const0_rtx; - return AS2 (cmp%W0,%1,%0); -}") - -(define_expand "tsthi" - [(set (cc0) - (match_operand:HI 0 "nonimmediate_operand" ""))] - "" - " -{ - i386_compare_gen = gen_tsthi_1; - i386_compare_op0 = operands[0]; - DONE; -}") - -(define_insn "tstqi_1" - [(set (cc0) - (match_operand:QI 0 "nonimmediate_operand" "qm"))] - "" - "* -{ - if (REG_P (operands[0])) - return AS2 (test%B0,%0,%0); - - operands[1] = const0_rtx; - return AS2 (cmp%B0,%1,%0); -}") - -(define_expand "tstqi" - [(set (cc0) - (match_operand:QI 0 "nonimmediate_operand" ""))] - "" - " -{ - i386_compare_gen = gen_tstqi_1; - i386_compare_op0 = operands[0]; - DONE; -}") - -(define_insn "tstsf_cc" - [(set (cc0) - (match_operand:SF 0 "register_operand" "f")) - (clobber (match_scratch:HI 1 "=a"))] - "TARGET_80387 && ! TARGET_IEEE_FP" - "* -{ - if (! STACK_TOP_P (operands[0])) - abort (); - - output_asm_insn (\"ftst\", operands); - - if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) - output_asm_insn (AS1 (fstp,%y0), operands); - - return output_fp_cc0_set (insn); -}") - -;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode -;; isn't IEEE compliant. - -(define_expand "tstsf" - [(parallel [(set (cc0) - (match_operand:SF 0 "register_operand" "")) - (clobber (match_scratch:HI 1 ""))])] - "TARGET_80387 && ! TARGET_IEEE_FP" - " -{ - i386_compare_gen = gen_tstsf_cc; - i386_compare_op0 = operands[0]; - DONE; -}") - -(define_insn "tstdf_cc" - [(set (cc0) - (match_operand:DF 0 "register_operand" "f")) - (clobber (match_scratch:HI 1 "=a"))] - "TARGET_80387 && ! TARGET_IEEE_FP" - "* -{ - if (! STACK_TOP_P (operands[0])) - abort (); - - output_asm_insn (\"ftst\", operands); - - if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) - output_asm_insn (AS1 (fstp,%y0), operands); - - return output_fp_cc0_set (insn); -}") - -;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode -;; isn't IEEE compliant. - -(define_expand "tstdf" - [(parallel [(set (cc0) - (match_operand:DF 0 "register_operand" "")) - (clobber (match_scratch:HI 1 ""))])] - "TARGET_80387 && ! TARGET_IEEE_FP" - " -{ - i386_compare_gen = gen_tstdf_cc; - i386_compare_op0 = operands[0]; - DONE; -}") - -(define_insn "tstxf_cc" - [(set (cc0) - (match_operand:XF 0 "register_operand" "f")) - (clobber (match_scratch:HI 1 "=a"))] - "TARGET_80387 && ! TARGET_IEEE_FP" - "* -{ - if (! STACK_TOP_P (operands[0])) - abort (); - - output_asm_insn (\"ftst\", operands); - - if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) - output_asm_insn (AS1 (fstp,%y0), operands); - - return output_fp_cc0_set (insn); -}") - -;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode -;; isn't IEEE compliant. - -(define_expand "tstxf" - [(parallel [(set (cc0) - (match_operand:XF 0 "register_operand" "")) - (clobber (match_scratch:HI 1 ""))])] - "TARGET_80387 && ! TARGET_IEEE_FP" - " -{ - i386_compare_gen = gen_tstxf_cc; - i386_compare_op0 = operands[0]; - DONE; -}") - -;;- compare instructions. See comments above tstM patterns about -;; expansion of these insns. - -(define_insn "cmpsi_1" - [(set (cc0) - (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r") - (match_operand:SI 1 "general_operand" "ri,mr")))] - "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" - "* -{ - if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM) - { - cc_status.flags |= CC_REVERSED; - return AS2 (cmp%L0,%0,%1); - } - return AS2 (cmp%L0,%1,%0); -}") - -(define_expand "cmpsi" - [(set (cc0) - (compare (match_operand:SI 0 "nonimmediate_operand" "") - (match_operand:SI 1 "general_operand" "")))] - "" - " -{ - if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) - operands[0] = force_reg (SImode, operands[0]); - - i386_compare_gen = gen_cmpsi_1; - i386_compare_op0 = operands[0]; - i386_compare_op1 = operands[1]; - DONE; -}") - -(define_insn "cmphi_1" - [(set (cc0) - (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r") - (match_operand:HI 1 "general_operand" "ri,mr")))] - "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" - "* -{ - if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM) - { - cc_status.flags |= CC_REVERSED; - return AS2 (cmp%W0,%0,%1); - } - return AS2 (cmp%W0,%1,%0); -}") - -(define_expand "cmphi" - [(set (cc0) - (compare (match_operand:HI 0 "nonimmediate_operand" "") - (match_operand:HI 1 "general_operand" "")))] - "" - " -{ - if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) - operands[0] = force_reg (HImode, operands[0]); - - i386_compare_gen = gen_cmphi_1; - i386_compare_op0 = operands[0]; - i386_compare_op1 = operands[1]; - DONE; -}") - -(define_insn "cmpqi_1" - [(set (cc0) - (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq") - (match_operand:QI 1 "general_operand" "qm,nq")))] - "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" - "* -{ - if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM) - { - cc_status.flags |= CC_REVERSED; - return AS2 (cmp%B0,%0,%1); - } - return AS2 (cmp%B0,%1,%0); -}") - -(define_expand "cmpqi" - [(set (cc0) - (compare (match_operand:QI 0 "nonimmediate_operand" "") - (match_operand:QI 1 "general_operand" "")))] - "" - " -{ - if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) - operands[0] = force_reg (QImode, operands[0]); - - i386_compare_gen = gen_cmpqi_1; - i386_compare_op0 = operands[0]; - i386_compare_op1 = operands[1]; - DONE; -}") - -;; These implement float point compares. For each of DFmode and -;; SFmode, there is the normal insn, and an insn where the second operand -;; is converted to the desired mode. - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:XF 0 "nonimmediate_operand" "f") - (match_operand:XF 1 "nonimmediate_operand" "f")])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387 - && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:XF 0 "register_operand" "f") - (float:XF - (match_operand:SI 1 "nonimmediate_operand" "rm"))])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(float:XF - (match_operand:SI 0 "nonimmediate_operand" "rm")) - (match_operand:XF 1 "register_operand" "f")])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:XF 0 "register_operand" "f") - (float_extend:XF - (match_operand:DF 1 "nonimmediate_operand" "fm"))])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:XF 0 "register_operand" "f") - (float_extend:XF - (match_operand:SF 1 "nonimmediate_operand" "fm"))])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f") - (match_operand:XF 1 "register_operand" "f"))) - (clobber (match_scratch:HI 2 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:DF 0 "nonimmediate_operand" "f,fm") - (match_operand:DF 1 "nonimmediate_operand" "fm,f")])) - (clobber (match_scratch:HI 3 "=a,a"))] - "TARGET_80387 - && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:DF 0 "register_operand" "f") - (float:DF - (match_operand:SI 1 "nonimmediate_operand" "rm"))])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(float:DF - (match_operand:SI 0 "nonimmediate_operand" "rm")) - (match_operand:DF 1 "register_operand" "f")])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:DF 0 "register_operand" "f") - (float_extend:DF - (match_operand:SF 1 "nonimmediate_operand" "fm"))])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(float_extend:DF - (match_operand:SF 0 "nonimmediate_operand" "fm")) - (match_operand:DF 1 "register_operand" "f")])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f") - (match_operand:DF 1 "register_operand" "f"))) - (clobber (match_scratch:HI 2 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -;; These two insns will never be generated by combine due to the mode of -;; the COMPARE. -;(define_insn "" -; [(set (cc0) -; (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f") -; (float_extend:DF -; (match_operand:SF 1 "register_operand" "f")))) -; (clobber (match_scratch:HI 2 "=a"))] -; "TARGET_80387" -; "* return output_float_compare (insn, operands);") -; -;(define_insn "" -; [(set (cc0) -; (compare:CCFPEQ (float_extend:DF -; (match_operand:SF 0 "register_operand" "f")) -; (match_operand:DF 1 "register_operand" "f"))) -; (clobber (match_scratch:HI 2 "=a"))] -; "TARGET_80387" -; "* return output_float_compare (insn, operands);") - -(define_insn "cmpsf_cc_1" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:SF 0 "nonimmediate_operand" "f,fm") - (match_operand:SF 1 "nonimmediate_operand" "fm,f")])) - (clobber (match_scratch:HI 3 "=a,a"))] - "TARGET_80387 - && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:SF 0 "register_operand" "f") - (float:SF - (match_operand:SI 1 "nonimmediate_operand" "rm"))])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(float:SF - (match_operand:SI 0 "nonimmediate_operand" "rm")) - (match_operand:SF 1 "register_operand" "f")])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f") - (match_operand:SF 1 "register_operand" "f"))) - (clobber (match_scratch:HI 2 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_expand "cmpxf" - [(set (cc0) - (compare (match_operand:XF 0 "register_operand" "") - (match_operand:XF 1 "nonimmediate_operand" "")))] - "TARGET_80387" - " -{ - i386_compare_gen = gen_cmpxf_cc; - i386_compare_gen_eq = gen_cmpxf_ccfpeq; - i386_compare_op0 = operands[0]; - i386_compare_op1 = operands[1]; - DONE; -}") - -(define_expand "cmpdf" - [(set (cc0) - (compare (match_operand:DF 0 "register_operand" "") - (match_operand:DF 1 "nonimmediate_operand" "")))] - "TARGET_80387" - " -{ - i386_compare_gen = gen_cmpdf_cc; - i386_compare_gen_eq = gen_cmpdf_ccfpeq; - i386_compare_op0 = operands[0]; - i386_compare_op1 = operands[1]; - DONE; -}") - -(define_expand "cmpsf" - [(set (cc0) - (compare (match_operand:SF 0 "register_operand" "") - (match_operand:SF 1 "nonimmediate_operand" "")))] - "TARGET_80387" - " -{ - i386_compare_gen = gen_cmpsf_cc; - i386_compare_gen_eq = gen_cmpsf_ccfpeq; - i386_compare_op0 = operands[0]; - i386_compare_op1 = operands[1]; - DONE; -}") - -(define_expand "cmpxf_cc" - [(parallel [(set (cc0) - (compare (match_operand:XF 0 "register_operand" "") - (match_operand:XF 1 "register_operand" ""))) - (clobber (match_scratch:HI 2 ""))])] - "TARGET_80387" - "") - -(define_expand "cmpxf_ccfpeq" - [(parallel [(set (cc0) - (compare:CCFPEQ (match_operand:XF 0 "register_operand" "") - (match_operand:XF 1 "register_operand" ""))) - (clobber (match_scratch:HI 2 ""))])] - "TARGET_80387" - " -{ - if (! register_operand (operands[1], XFmode)) - operands[1] = copy_to_mode_reg (XFmode, operands[1]); -}") - -(define_expand "cmpdf_cc" - [(parallel [(set (cc0) - (compare (match_operand:DF 0 "register_operand" "") - (match_operand:DF 1 "register_operand" ""))) - (clobber (match_scratch:HI 2 ""))])] - "TARGET_80387" - "") - -(define_expand "cmpdf_ccfpeq" - [(parallel [(set (cc0) - (compare:CCFPEQ (match_operand:DF 0 "register_operand" "") - (match_operand:DF 1 "register_operand" ""))) - (clobber (match_scratch:HI 2 ""))])] - "TARGET_80387" - " -{ - if (! register_operand (operands[1], DFmode)) - operands[1] = copy_to_mode_reg (DFmode, operands[1]); -}") - -(define_expand "cmpsf_cc" - [(parallel [(set (cc0) - (compare (match_operand:SF 0 "register_operand" "") - (match_operand:SF 1 "register_operand" ""))) - (clobber (match_scratch:HI 2 ""))])] - "TARGET_80387" - "") - -(define_expand "cmpsf_ccfpeq" - [(parallel [(set (cc0) - (compare:CCFPEQ (match_operand:SF 0 "register_operand" "") - (match_operand:SF 1 "register_operand" ""))) - (clobber (match_scratch:HI 2 ""))])] - "TARGET_80387" - " -{ - if (! register_operand (operands[1], SFmode)) - operands[1] = copy_to_mode_reg (SFmode, operands[1]); -}") - -;; logical compare - -(define_insn "" - [(set (cc0) - (and:SI (match_operand:SI 0 "general_operand" "%ro") - (match_operand:SI 1 "general_operand" "ri")))] - "" - "* -{ - /* For small integers, we may actually use testb. */ - if (GET_CODE (operands[1]) == CONST_INT - && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) - && (! REG_P (operands[0]) || QI_REG_P (operands[0]))) - { - /* We may set the sign bit spuriously. */ - - if ((INTVAL (operands[1]) & ~0xff) == 0) - { - cc_status.flags |= CC_NOT_NEGATIVE; - return AS2 (test%B0,%1,%b0); - } - - if ((INTVAL (operands[1]) & ~0xff00) == 0) - { - cc_status.flags |= CC_NOT_NEGATIVE; - operands[1] = GEN_INT (INTVAL (operands[1]) >> 8); - - if (QI_REG_P (operands[0])) - return AS2 (test%B0,%1,%h0); - else - { - operands[0] = adj_offsettable_operand (operands[0], 1); - return AS2 (test%B0,%1,%b0); - } - } - - if (GET_CODE (operands[0]) == MEM - && (INTVAL (operands[1]) & ~0xff0000) == 0) - { - cc_status.flags |= CC_NOT_NEGATIVE; - operands[1] = GEN_INT (INTVAL (operands[1]) >> 16); - operands[0] = adj_offsettable_operand (operands[0], 2); - return AS2 (test%B0,%1,%b0); - } - - if (GET_CODE (operands[0]) == MEM - && (INTVAL (operands[1]) & ~0xff000000) == 0) - { - operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff); - operands[0] = adj_offsettable_operand (operands[0], 3); - return AS2 (test%B0,%1,%b0); - } - } - - if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM) - return AS2 (test%L0,%1,%0); - - return AS2 (test%L1,%0,%1); -}") - -(define_insn "" - [(set (cc0) - (and:HI (match_operand:HI 0 "general_operand" "%ro") - (match_operand:HI 1 "general_operand" "ri")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT - && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) - && (! REG_P (operands[0]) || QI_REG_P (operands[0]))) - { - if ((INTVAL (operands[1]) & 0xff00) == 0) - { - /* ??? This might not be necessary. */ - if (INTVAL (operands[1]) & 0xffff0000) - operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); - - /* We may set the sign bit spuriously. */ - cc_status.flags |= CC_NOT_NEGATIVE; - return AS2 (test%B0,%1,%b0); - } - - if ((INTVAL (operands[1]) & 0xff) == 0) - { - operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff); - - if (QI_REG_P (operands[0])) - return AS2 (test%B0,%1,%h0); - else - { - operands[0] = adj_offsettable_operand (operands[0], 1); - return AS2 (test%B0,%1,%b0); - } - } - } - - if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM) - return AS2 (test%W0,%1,%0); - - return AS2 (test%W1,%0,%1); -}") - -(define_insn "" - [(set (cc0) - (and:QI (match_operand:QI 0 "general_operand" "%qm") - (match_operand:QI 1 "general_operand" "qi")))] - "" - "* -{ - if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM) - return AS2 (test%B0,%1,%0); - - return AS2 (test%B1,%0,%1); -}") - -;; move instructions. -;; There is one for each machine mode, -;; and each is preceded by a corresponding push-insn pattern -;; (since pushes are not general_operands on the 386). - -(define_insn "" - [(set (match_operand:SI 0 "push_operand" "=<") - (match_operand:SI 1 "general_operand" "g"))] - "TARGET_386" - "push%L0 %1") - -;; On a 486, it is faster to move MEM to a REG and then push, rather than -;; push MEM directly. - -(define_insn "" - [(set (match_operand:SI 0 "push_operand" "=<") - (match_operand:SI 1 "nonmemory_operand" "ri"))] - "!TARGET_386 && TARGET_MOVE" - "push%L0 %1") - -(define_insn "" - [(set (match_operand:SI 0 "push_operand" "=<") - (match_operand:SI 1 "general_operand" "ri"))] - "!TARGET_386 && !TARGET_MOVE" - "push%L0 %1") - -;; General case of fullword move. - -;; If generating PIC code and operands[1] is a symbolic CONST, emit a -;; move to get the address of the symbolic object from the GOT. - -(define_expand "movsi" - [(set (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "general_operand" ""))] - "" - " -{ - extern int flag_pic; - - if (flag_pic && SYMBOLIC_CONST (operands[1])) - emit_pic_move (operands, SImode); - - /* Don't generate memory->memory moves, go through a register */ - else if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) == MEM - && GET_CODE (operands[1]) == MEM) - { - operands[1] = force_reg (SImode, operands[1]); - } -}") - -;; On i486, incl reg is faster than movl $1,reg. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g,r") - (match_operand:SI 1 "general_operand" "ri,m"))] - "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" - "* -{ - rtx link; - if (operands[1] == const0_rtx && REG_P (operands[0])) - return AS2 (xor%L0,%0,%0); - - if (operands[1] == const1_rtx - && (link = find_reg_note (insn, REG_WAS_0, 0)) - /* Make sure the insn that stored the 0 is still present. */ - && ! INSN_DELETED_P (XEXP (link, 0)) - && GET_CODE (XEXP (link, 0)) != NOTE - /* Make sure cross jumping didn't happen here. */ - && no_labels_between_p (XEXP (link, 0), insn) - /* Make sure the reg hasn't been clobbered. */ - && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) - /* Fastest way to change a 0 to a 1. */ - return AS1 (inc%L0,%0); - - if (flag_pic && SYMBOLIC_CONST (operands[1])) - return AS2 (lea%L0,%a1,%0); - - return AS2 (mov%L0,%1,%0); -}") - -(define_insn "" - [(set (match_operand:HI 0 "push_operand" "=<") - (match_operand:HI 1 "general_operand" "g"))] - "TARGET_386" - "push%W0 %1") - -(define_insn "" - [(set (match_operand:HI 0 "push_operand" "=<") - (match_operand:HI 1 "nonmemory_operand" "ri"))] - "!TARGET_386 && TARGET_MOVE" - "push%W0 %1") - -(define_insn "" - [(set (match_operand:HI 0 "push_operand" "=<") - (match_operand:HI 1 "general_operand" "ri"))] - "!TARGET_386 && !TARGET_MOVE" - "push%W0 %1") - -;; On i486, an incl and movl are both faster than incw and movw. - -(define_expand "movhi" - [(set (match_operand:HI 0 "general_operand" "") - (match_operand:HI 1 "general_operand" ""))] - "" - " -{ - /* Don't generate memory->memory moves, go through a register */ - if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) == MEM - && GET_CODE (operands[1]) == MEM) - { - operands[1] = force_reg (HImode, operands[1]); - } -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g,r") - (match_operand:HI 1 "general_operand" "ri,m"))] - "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" - "* -{ - rtx link; - if (REG_P (operands[0]) && operands[1] == const0_rtx) - return AS2 (xor%L0,%k0,%k0); - - if (REG_P (operands[0]) && operands[1] == const1_rtx - && (link = find_reg_note (insn, REG_WAS_0, 0)) - /* Make sure the insn that stored the 0 is still present. */ - && ! INSN_DELETED_P (XEXP (link, 0)) - && GET_CODE (XEXP (link, 0)) != NOTE - /* Make sure cross jumping didn't happen here. */ - && no_labels_between_p (XEXP (link, 0), insn) - /* Make sure the reg hasn't been clobbered. */ - && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) - /* Fastest way to change a 0 to a 1. */ - return AS1 (inc%L0,%k0); - - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - return AS2 (mov%L0,%k1,%k0); - else if (CONSTANT_P (operands[1])) - return AS2 (mov%L0,%1,%k0); - } - - return AS2 (mov%W0,%1,%0); -}") - -(define_expand "movstricthi" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "")) - (match_operand:HI 1 "general_operand" ""))] - "" - " -{ - /* Don't generate memory->memory moves, go through a register */ - if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) == MEM - && GET_CODE (operands[1]) == MEM) - { - operands[1] = force_reg (HImode, operands[1]); - } -}") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r")) - (match_operand:HI 1 "general_operand" "ri,m"))] - "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" - "* -{ - rtx link; - if (operands[1] == const0_rtx && REG_P (operands[0])) - return AS2 (xor%W0,%0,%0); - - if (operands[1] == const1_rtx - && (link = find_reg_note (insn, REG_WAS_0, 0)) - /* Make sure the insn that stored the 0 is still present. */ - && ! INSN_DELETED_P (XEXP (link, 0)) - && GET_CODE (XEXP (link, 0)) != NOTE - /* Make sure cross jumping didn't happen here. */ - && no_labels_between_p (XEXP (link, 0), insn) - /* Make sure the reg hasn't been clobbered. */ - && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) - /* Fastest way to change a 0 to a 1. */ - return AS1 (inc%W0,%0); - - return AS2 (mov%W0,%1,%0); -}") - -;; emit_push_insn when it calls move_by_pieces -;; requires an insn to "push a byte". -;; But actually we use pushw, which has the effect of rounding -;; the amount pushed up to a halfword. -(define_insn "" - [(set (match_operand:QI 0 "push_operand" "=<") - (match_operand:QI 1 "immediate_operand" "n"))] - "" - "* return AS1 (push%W0,%1);") - -(define_insn "" - [(set (match_operand:QI 0 "push_operand" "=<") - (match_operand:QI 1 "nonimmediate_operand" "q"))] - "!TARGET_MOVE" - "* -{ - operands[1] = gen_rtx (REG, HImode, REGNO (operands[1])); - return AS1 (push%W0,%1); -}") - -(define_insn "" - [(set (match_operand:QI 0 "push_operand" "=<") - (match_operand:QI 1 "register_operand" "q"))] - "TARGET_MOVE" - "* -{ - operands[1] = gen_rtx (REG, HImode, REGNO (operands[1])); - return AS1 (push%W0,%1); -}") - -;; On i486, incb reg is faster than movb $1,reg. - -;; ??? Do a recognizer for zero_extract that looks just like this, but reads -;; or writes %ah, %bh, %ch, %dh. - -(define_expand "movqi" - [(set (match_operand:QI 0 "general_operand" "") - (match_operand:QI 1 "general_operand" ""))] - "" - " -{ - /* Don't generate memory->memory moves, go through a register */ - if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) == MEM - && GET_CODE (operands[1]) == MEM) - { - operands[1] = force_reg (QImode, operands[1]); - } -}") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=q,*r,qm") - (match_operand:QI 1 "general_operand" "*g,q,qn"))] - "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" - "* -{ - rtx link; - if (operands[1] == const0_rtx && REG_P (operands[0])) - return AS2 (xor%B0,%0,%0); - - if (operands[1] == const1_rtx - && (link = find_reg_note (insn, REG_WAS_0, 0)) - /* Make sure the insn that stored the 0 is still present. */ - && ! INSN_DELETED_P (XEXP (link, 0)) - && GET_CODE (XEXP (link, 0)) != NOTE - /* Make sure cross jumping didn't happen here. */ - && no_labels_between_p (XEXP (link, 0), insn) - /* Make sure the reg hasn't been clobbered. */ - && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) - /* Fastest way to change a 0 to a 1. */ - return AS1 (inc%B0,%0); - - /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */ - if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1])) - return (AS2 (mov%L0,%k1,%k0)); - - return (AS2 (mov%B0,%1,%0)); -}") - -;; If it becomes necessary to support movstrictqi into %esi or %edi, -;; use the insn sequence: -;; -;; shrdl $8,srcreg,dstreg -;; rorl $24,dstreg -;; -;; If operands[1] is a constant, then an andl/orl sequence would be -;; faster. - -(define_expand "movstrictqi" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "")) - (match_operand:QI 1 "general_operand" ""))] - "" - " -{ - /* Don't generate memory->memory moves, go through a register */ - if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) == MEM - && GET_CODE (operands[1]) == MEM) - { - operands[1] = force_reg (QImode, operands[1]); - } -}") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+qm,q")) - (match_operand:QI 1 "general_operand" "*qn,m"))] - "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" - "* -{ - rtx link; - if (operands[1] == const0_rtx && REG_P (operands[0])) - return AS2 (xor%B0,%0,%0); - - if (operands[1] == const1_rtx - && (link = find_reg_note (insn, REG_WAS_0, 0)) - /* Make sure the insn that stored the 0 is still present. */ - && ! INSN_DELETED_P (XEXP (link, 0)) - && GET_CODE (XEXP (link, 0)) != NOTE - /* Make sure cross jumping didn't happen here. */ - && no_labels_between_p (XEXP (link, 0), insn) - /* Make sure the reg hasn't been clobbered. */ - && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) - /* Fastest way to change a 0 to a 1. */ - return AS1 (inc%B0,%0); - - /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */ - if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1])) - { - abort (); - return (AS2 (mov%L0,%k1,%k0)); - } - - return AS2 (mov%B0,%1,%0); -}") - -(define_expand "movsf" - [(set (match_operand:SF 0 "general_operand" "") - (match_operand:SF 1 "general_operand" ""))] - "" - " -{ - /* Special case memory->memory moves and pushes */ - if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) == MEM - && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], SFmode))) - { - rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], SFmode)) - ? gen_movsf_push - : gen_movsf_mem; - - emit_insn ((*genfunc) (operands[0], operands[1])); - DONE; - } - - /* If we are loading a floating point constant that isn't 0 or 1 into a register, - indicate we need the pic register loaded. This could be optimized into stores - of constants if the target eventually moves to memory, but better safe than - sorry. */ - if (flag_pic - && GET_CODE (operands[0]) != MEM - && GET_CODE (operands[1]) == CONST_DOUBLE - && !standard_80387_constant_p (operands[1])) - { - current_function_uses_pic_offset_table = 1; - } -}") - -(define_insn "movsf_push_nomove" - [(set (match_operand:SF 0 "push_operand" "=<,<") - (match_operand:SF 1 "general_operand" "gF,f"))] - "!TARGET_MOVE" - "* -{ - if (STACK_REG_P (operands[1])) - { - rtx xops[3]; - - if (! STACK_TOP_P (operands[1])) - abort (); - - xops[0] = AT_SP (SFmode); - xops[1] = GEN_INT (4); - xops[2] = stack_pointer_rtx; - - output_asm_insn (AS2 (sub%L2,%1,%2), xops); - - if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) - output_asm_insn (AS1 (fstp%S0,%0), xops); - else - output_asm_insn (AS1 (fst%S0,%0), xops); - RET; - } - return AS1 (push%L1,%1); -}") - -(define_insn "movsf_push" - [(set (match_operand:SF 0 "push_operand" "=<,<,<,<") - (match_operand:SF 1 "general_operand" "rF,f,m,m")) - (clobber (match_scratch:SI 2 "=X,X,r,X"))] - "" - "* -{ - if (STACK_REG_P (operands[1])) - { - rtx xops[3]; - - if (! STACK_TOP_P (operands[1])) - abort (); - - xops[0] = AT_SP (SFmode); - xops[1] = GEN_INT (4); - xops[2] = stack_pointer_rtx; - - output_asm_insn (AS2 (sub%L2,%1,%2), xops); - - if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) - output_asm_insn (AS1 (fstp%S0,%0), xops); - else - output_asm_insn (AS1 (fst%S0,%0), xops); - RET; - } - - else if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != REG) - return AS1 (push%L1,%1); - - else - { - output_asm_insn (AS2 (mov%L2,%1,%2), operands); - return AS1 (push%L2,%2); - } -}") - -;; Special memory<->memory pattern that combine will recreate from the -;; moves to pseudos. -(define_insn "movsf_mem" - [(set (match_operand:SF 0 "memory_operand" "=m") - (match_operand:SF 1 "memory_operand" "m")) - (clobber (match_scratch:SI 2 "=&r"))] - "" - "* -{ - output_asm_insn (AS2 (mov%L2,%1,%2), operands); - return AS2 (mov%L0,%2,%0); -}") - -;; For the purposes of regclass, prefer FLOAT_REGS. -(define_insn "movsf_normal" - [(set (match_operand:SF 0 "general_operand" "=*rfm,*rf,f,!*rm") - (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))] - "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" - "* -{ - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - /* First handle a `pop' insn or a `fld %st(0)' */ - - if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) - { - if (stack_top_dies) - return AS1 (fstp,%y0); - else - return AS1 (fld,%y0); - } - - /* Handle a transfer between the 387 and a 386 register */ - - if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } - - if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies); - RET; - } - - /* Handle other kinds of writes from the 387 */ - - if (STACK_TOP_P (operands[1])) - { - if (stack_top_dies) - return AS1 (fstp%z0,%y0); - else - return AS1 (fst%z0,%y0); - } - - /* Handle other kinds of reads to the 387 */ - - if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE) - return output_move_const_single (operands); - - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); - - /* Handle all SFmode moves not involving the 387 */ - - return singlemove_string (operands); -}") - -(define_insn "swapsf" - [(set (match_operand:SF 0 "register_operand" "f") - (match_operand:SF 1 "register_operand" "f")) - (set (match_dup 1) - (match_dup 0))] - "" - "* -{ - if (STACK_TOP_P (operands[0])) - return AS1 (fxch,%1); - else - return AS1 (fxch,%0); -}") - -(define_expand "movdf" - [(set (match_operand:DF 0 "general_operand" "") - (match_operand:DF 1 "general_operand" ""))] - "" - " -{ - /* Special case memory->memory moves and pushes */ - if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) == MEM - && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], DFmode))) - { - rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], DFmode)) - ? gen_movdf_push - : gen_movdf_mem; - - emit_insn ((*genfunc) (operands[0], operands[1])); - DONE; - } - - /* If we are loading a floating point constant that isn't 0 or 1 into a register, - indicate we need the pic register loaded. This could be optimized into stores - of constants if the target eventually moves to memory, but better safe than - sorry. */ - if (flag_pic - && GET_CODE (operands[0]) != MEM - && GET_CODE (operands[1]) == CONST_DOUBLE - && !standard_80387_constant_p (operands[1])) - { - current_function_uses_pic_offset_table = 1; - } -}") - -(define_insn "movdf_push_nomove" - [(set (match_operand:DF 0 "push_operand" "=<,<") - (match_operand:DF 1 "general_operand" "gF,f"))] - "!TARGET_MOVE" - "* -{ - if (STACK_REG_P (operands[1])) - { - rtx xops[3]; - - xops[0] = AT_SP (SFmode); - xops[1] = GEN_INT (8); - xops[2] = stack_pointer_rtx; - - output_asm_insn (AS2 (sub%L2,%1,%2), xops); - - if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) - output_asm_insn (AS1 (fstp%Q0,%0), xops); - else - output_asm_insn (AS1 (fst%Q0,%0), xops); - - RET; - } - else - return output_move_double (operands); -}") - -(define_insn "movdf_push" - [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<") - (match_operand:DF 1 "general_operand" "rF,f,o,o,o")) - (clobber (match_scratch:SI 2 "=X,X,&r,&r,X")) - (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))] - "" - "* -{ - if (STACK_REG_P (operands[1])) - { - rtx xops[3]; - - xops[0] = AT_SP (SFmode); - xops[1] = GEN_INT (8); - xops[2] = stack_pointer_rtx; - - output_asm_insn (AS2 (sub%L2,%1,%2), xops); - - if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) - output_asm_insn (AS1 (fstp%Q0,%0), xops); - else - output_asm_insn (AS1 (fst%Q0,%0), xops); - - RET; - } - - else if (GET_CODE (operands[1]) != MEM) - return output_move_double (operands); - - else - return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 2, 4); -}") - -(define_insn "movdf_mem" - [(set (match_operand:DF 0 "memory_operand" "=o,o") - (match_operand:DF 1 "memory_operand" "o,o")) - (clobber (match_scratch:SI 2 "=&r,&r")) - (clobber (match_scratch:SI 3 "=&r,X"))] - "" - "* return output_move_memory (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);") - -;; For the purposes of regclass, prefer FLOAT_REGS. -(define_insn "movdf_normal" - [(set (match_operand:DF 0 "general_operand" "=f,fm,!*rf,!*rm") - (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))] - "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" - "* -{ - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - /* First handle a `pop' insn or a `fld %st(0)' */ - - if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) - { - if (stack_top_dies) - return AS1 (fstp,%y0); - else - return AS1 (fld,%y0); - } - - /* Handle a transfer between the 387 and a 386 register */ - - if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } - - if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies); - RET; - } - - /* Handle other kinds of writes from the 387 */ - - if (STACK_TOP_P (operands[1])) - { - if (stack_top_dies) - return AS1 (fstp%z0,%y0); - else - return AS1 (fst%z0,%y0); - } - - /* Handle other kinds of reads to the 387 */ - - if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE) - return output_move_const_single (operands); - - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); - - /* Handle all DFmode moves not involving the 387 */ - - return output_move_double (operands); -}") - -(define_insn "swapdf" - [(set (match_operand:DF 0 "register_operand" "f") - (match_operand:DF 1 "register_operand" "f")) - (set (match_dup 1) - (match_dup 0))] - "" - "* -{ - if (STACK_TOP_P (operands[0])) - return AS1 (fxch,%1); - else - return AS1 (fxch,%0); -}") - -(define_expand "movxf" - [(set (match_operand:XF 0 "general_operand" "") - (match_operand:XF 1 "general_operand" ""))] - "" - " -{ - /* Special case memory->memory moves and pushes */ - if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) == MEM - && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], XFmode))) - { - rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], XFmode)) - ? gen_movxf_push - : gen_movxf_mem; - - emit_insn ((*genfunc) (operands[0], operands[1])); - DONE; - } - - /* If we are loading a floating point constant that isn't 0 or 1 into a register, - indicate we need the pic register loaded. This could be optimized into stores - of constants if the target eventually moves to memory, but better safe than - sorry. */ - if (flag_pic - && GET_CODE (operands[0]) != MEM - && GET_CODE (operands[1]) == CONST_DOUBLE - && !standard_80387_constant_p (operands[1])) - { - current_function_uses_pic_offset_table = 1; - } -}") - - -(define_insn "movxf_push_nomove" - [(set (match_operand:XF 0 "push_operand" "=<,<") - (match_operand:XF 1 "general_operand" "gF,f"))] - "!TARGET_MOVE" - "* -{ - if (STACK_REG_P (operands[1])) - { - rtx xops[3]; - - xops[0] = AT_SP (SFmode); - xops[1] = GEN_INT (12); - xops[2] = stack_pointer_rtx; - - output_asm_insn (AS2 (sub%L2,%1,%2), xops); - output_asm_insn (AS1 (fstp%T0,%0), xops); - if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) - output_asm_insn (AS1 (fld%T0,%0), xops); - - RET; - } - else - return output_move_double (operands); - }") - -(define_insn "movxf_push" - [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<") - (match_operand:XF 1 "general_operand" "rF,f,o,o,o")) - (clobber (match_scratch:SI 2 "=X,X,&r,&r,X")) - (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))] - "" - "* -{ - if (STACK_REG_P (operands[1])) - { - rtx xops[3]; - - xops[0] = AT_SP (SFmode); - xops[1] = GEN_INT (12); - xops[2] = stack_pointer_rtx; - - output_asm_insn (AS2 (sub%L2,%1,%2), xops); - output_asm_insn (AS1 (fstp%T0,%0), xops); - if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) - output_asm_insn (AS1 (fld%T0,%0), xops); - - RET; - } - - else if (GET_CODE (operands[1]) != MEM - || GET_CODE (operands[2]) != REG) - return output_move_double (operands); - - else - return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 2, 4); -}") - -(define_insn "movxf_mem" - [(set (match_operand:XF 0 "memory_operand" "=o,o") - (match_operand:XF 1 "memory_operand" "o,o")) - (clobber (match_scratch:SI 2 "=&r,&r")) - (clobber (match_scratch:SI 3 "=&r,X"))] - "" - "* return output_move_memory (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);") - -(define_insn "movxf_normal" - [(set (match_operand:XF 0 "general_operand" "=f,fm,!*rf,!*rm") - (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))] - "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" - "* -{ - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - /* First handle a `pop' insn or a `fld %st(0)' */ - - if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) - { - if (stack_top_dies) - return AS1 (fstp,%y0); - else - return AS1 (fld,%y0); - } - - /* Handle a transfer between the 387 and a 386 register */ - - if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } - - if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies); - RET; - } - - /* Handle other kinds of writes from the 387 */ - - if (STACK_TOP_P (operands[1])) - { - output_asm_insn (AS1 (fstp%z0,%y0), operands); - if (! stack_top_dies) - return AS1 (fld%z0,%y0); - - RET; - } - - /* Handle other kinds of reads to the 387 */ - - if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE) - return output_move_const_single (operands); - - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); - - /* Handle all XFmode moves not involving the 387 */ - - return output_move_double (operands); -}") - -(define_insn "swapxf" - [(set (match_operand:XF 0 "register_operand" "f") - (match_operand:XF 1 "register_operand" "f")) - (set (match_dup 1) - (match_dup 0))] - "" - "* -{ - if (STACK_TOP_P (operands[0])) - return AS1 (fxch,%1); - else - return AS1 (fxch,%0); -}") - -(define_insn "" - [(set (match_operand:DI 0 "push_operand" "=<,<,<,<") - (match_operand:DI 1 "general_operand" "riF,o,o,o")) - (clobber (match_scratch:SI 2 "=X,&r,&r,X")) - (clobber (match_scratch:SI 3 "=X,&r,X,X"))] - "" - "* -{ - if (GET_CODE (operands[1]) != MEM) - return output_move_double (operands); - - else - return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode), 2, 4); -}") - -(define_insn "movdi" - [(set (match_operand:DI 0 "general_operand" "=o,o,r,rm") - (match_operand:DI 1 "general_operand" "o,o,m,riF")) - (clobber (match_scratch:SI 2 "=&r,&r,X,X")) - (clobber (match_scratch:SI 3 "=&r,X,X,X"))] - "" - "* -{ - rtx low[2], high[2], xop[6]; - - if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) - return output_move_double (operands); - else - return output_move_memory (operands, insn, GET_MODE_SIZE (DImode), 2, 4); -}") - - -;;- conversion instructions -;;- NONE - -;;- zero extension instructions -;; See comments by `andsi' for when andl is faster than movzx. - -(define_insn "zero_extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=r") - (zero_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "rm")))] - "" - "* -{ - if ((!TARGET_386 || REGNO (operands[0]) == 0) - && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])) - { - rtx xops[2]; - xops[0] = operands[0]; - xops[1] = GEN_INT (0xffff); - output_asm_insn (AS2 (and%L0,%1,%k0), xops); - RET; - } - -#ifdef INTEL_SYNTAX - return AS2 (movzx,%1,%0); -#else - return AS2 (movz%W0%L0,%1,%0); -#endif -}") - -(define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=r") - (zero_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "qm")))] - "" - "* -{ - if ((!TARGET_386 || REGNO (operands[0]) == 0) - && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])) - { - rtx xops[2]; - xops[0] = operands[0]; - xops[1] = GEN_INT (0xff); - output_asm_insn (AS2 (and%L0,%1,%k0), xops); - RET; - } - -#ifdef INTEL_SYNTAX - return AS2 (movzx,%1,%0); -#else - return AS2 (movz%B0%W0,%1,%0); -#endif -}") - -(define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=r") - (zero_extend:SI - (match_operand:QI 1 "nonimmediate_operand" "qm")))] - "" - "* -{ - if ((!TARGET_386 || REGNO (operands[0]) == 0) - && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])) - { - rtx xops[2]; - xops[0] = operands[0]; - xops[1] = GEN_INT (0xff); - output_asm_insn (AS2 (and%L0,%1,%k0), xops); - RET; - } - -#ifdef INTEL_SYNTAX - return AS2 (movzx,%1,%0); -#else - return AS2 (movz%B0%L0,%1,%0); -#endif -}") - -(define_insn "zero_extendsidi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI - (match_operand:SI 1 "register_operand" "0")))] - "" - "* -{ - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return AS2 (xor%L0,%0,%0); -}") - -;;- sign extension instructions - -(define_insn "extendsidi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (sign_extend:DI - (match_operand:SI 1 "register_operand" "0")))] - "" - "* -{ - if (REGNO (operands[0]) == 0) - { - /* This used to be cwtl, but that extends HI to SI somehow. */ -#ifdef INTEL_SYNTAX - return \"cdq\"; -#else - return \"cltd\"; -#endif - } - - operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - output_asm_insn (AS2 (mov%L0,%0,%1), operands); - - operands[0] = GEN_INT (31); - return AS2 (sar%L1,%0,%1); -}") - -;; Note that the i386 programmers' manual says that the opcodes -;; are named movsx..., but the assembler on Unix does not accept that. -;; We use what the Unix assembler expects. - -(define_insn "extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=r") - (sign_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "rm")))] - "" - "* -{ - if (REGNO (operands[0]) == 0 - && REG_P (operands[1]) && REGNO (operands[1]) == 0) -#ifdef INTEL_SYNTAX - return \"cwde\"; -#else - return \"cwtl\"; -#endif - -#ifdef INTEL_SYNTAX - return AS2 (movsx,%1,%0); -#else - return AS2 (movs%W0%L0,%1,%0); -#endif -}") - -(define_insn "extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=r") - (sign_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "qm")))] - "" - "* -{ - if (REGNO (operands[0]) == 0 - && REG_P (operands[1]) && REGNO (operands[1]) == 0) - return \"cbtw\"; - -#ifdef INTEL_SYNTAX - return AS2 (movsx,%1,%0); -#else - return AS2 (movs%B0%W0,%1,%0); -#endif -}") - -(define_insn "extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=r") - (sign_extend:SI - (match_operand:QI 1 "nonimmediate_operand" "qm")))] - "" - "* -{ -#ifdef INTEL_SYNTAX - return AS2 (movsx,%1,%0); -#else - return AS2 (movs%B0%L0,%1,%0); -#endif -}") - -;; Conversions between float and double. - -(define_insn "extendsfdf2" - [(set (match_operand:DF 0 "general_operand" "=fm,f") - (float_extend:DF - (match_operand:SF 1 "general_operand" "f,fm")))] - "TARGET_80387" - "* -{ - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } - - if (NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies); - RET; - } - - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); - - if (GET_CODE (operands[0]) == MEM) - { - if (stack_top_dies) - return AS1 (fstp%z0,%y0); - else - return AS1 (fst%z0,%y0); - } - - abort (); -}") - -(define_insn "extenddfxf2" - [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r") - (float_extend:XF - (match_operand:DF 1 "general_operand" "f,fm,!*r,f")))] - "TARGET_80387" - "* -{ - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } - - if (NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies); - RET; - } - - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); - - if (GET_CODE (operands[0]) == MEM) - { - output_asm_insn (AS1 (fstp%z0,%y0), operands); - if (! stack_top_dies) - return AS1 (fld%z0,%y0); - RET; - } - - abort (); -}") - -(define_insn "extendsfxf2" - [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r") - (float_extend:XF - (match_operand:SF 1 "general_operand" "f,fm,!*r,f")))] - "TARGET_80387" - "* -{ - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } - - if (NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies); - RET; - } - - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); - - if (GET_CODE (operands[0]) == MEM) - { - output_asm_insn (AS1 (fstp%z0,%y0), operands); - if (! stack_top_dies) - return AS1 (fld%z0,%y0); - RET; - } - - abort (); -}") - -(define_expand "truncdfsf2" - [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") - (float_truncate:SF - (match_operand:DF 1 "register_operand" ""))) - (clobber (match_dup 2))])] - "TARGET_80387" - " -{ - operands[2] = (rtx) assign_386_stack_local (SFmode, 0); -}") - -;; This cannot output into an f-reg because there is no way to be sure -;; of truncating in that case. Otherwise this is just like a simple move -;; insn. So we pretend we can output to a reg in order to get better -;; register preferencing, but we really use a stack slot. - -(define_insn "" - [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m") - (float_truncate:SF - (match_operand:DF 1 "register_operand" "0,f"))) - (clobber (match_operand:SF 2 "memory_operand" "m,m"))] - "TARGET_80387" - "* -{ - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - if (GET_CODE (operands[0]) == MEM) - { - if (stack_top_dies) - return AS1 (fstp%z0,%0); - else - return AS1 (fst%z0,%0); - } - else if (STACK_TOP_P (operands[0])) - { - output_asm_insn (AS1 (fstp%z2,%y2), operands); - return AS1 (fld%z2,%y2); - } - else - abort (); -}") - -(define_insn "truncxfsf2" - [(set (match_operand:SF 0 "general_operand" "=m,!*r") - (float_truncate:SF - (match_operand:XF 1 "register_operand" "f,f")))] - "TARGET_80387" - "* -{ - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - if (NON_STACK_REG_P (operands[0])) - { - if (stack_top_dies == 0) - { - output_asm_insn (AS1 (fld,%y1), operands); - stack_top_dies = 1; - } - output_to_reg (operands[0], stack_top_dies); - RET; - } - else if (GET_CODE (operands[0]) == MEM) - { - if (stack_top_dies) - return AS1 (fstp%z0,%0); - else - { - output_asm_insn (AS1 (fld,%y1), operands); - return AS1 (fstp%z0,%0); - } - } - else - abort (); -}") - -(define_insn "truncxfdf2" - [(set (match_operand:DF 0 "general_operand" "=m,!*r") - (float_truncate:DF - (match_operand:XF 1 "register_operand" "f,f")))] - "TARGET_80387" - "* -{ - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - if (NON_STACK_REG_P (operands[0])) - { - if (stack_top_dies == 0) - { - output_asm_insn (AS1 (fld,%y1), operands); - stack_top_dies = 1; - } - output_to_reg (operands[0], stack_top_dies); - RET; - } - else if (GET_CODE (operands[0]) == MEM) - { - if (stack_top_dies) - return AS1 (fstp%z0,%0); - else - { - output_asm_insn (AS1 (fld,%y1), operands); - return AS1 (fstp%z0,%0); - } - } - else - abort (); -}") - - -;; The 387 requires that the stack top dies after converting to DImode. - -;; Represent an unsigned conversion from SImode to MODE_FLOAT by first -;; doing a signed conversion to DImode, and then taking just the low -;; part. - -(define_expand "fixuns_truncxfsi2" - [(set (match_dup 4) - (match_operand:XF 1 "register_operand" "")) - (parallel [(set (match_dup 2) - (fix:DI (fix:XF (match_dup 4)))) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6)) - (clobber (match_scratch:SI 7 ""))]) - (set (match_operand:SI 0 "general_operand" "") - (match_dup 3))] - "TARGET_80387" - " -{ - operands[2] = gen_reg_rtx (DImode); - operands[3] = gen_lowpart (SImode, operands[2]); - operands[4] = gen_reg_rtx (XFmode); - operands[5] = (rtx) assign_386_stack_local (SImode, 0); - operands[6] = (rtx) assign_386_stack_local (SImode, 1); -}") - -(define_expand "fixuns_truncdfsi2" - [(set (match_dup 4) - (match_operand:DF 1 "register_operand" "")) - (parallel [(set (match_dup 2) - (fix:DI (fix:DF (match_dup 4)))) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6)) - (clobber (match_scratch:SI 7 ""))]) - (set (match_operand:SI 0 "general_operand" "") - (match_dup 3))] - "TARGET_80387" - " -{ - operands[2] = gen_reg_rtx (DImode); - operands[3] = gen_lowpart (SImode, operands[2]); - operands[4] = gen_reg_rtx (DFmode); - operands[5] = (rtx) assign_386_stack_local (SImode, 0); - operands[6] = (rtx) assign_386_stack_local (SImode, 1); -}") - -(define_expand "fixuns_truncsfsi2" - [(set (match_dup 4) - (match_operand:SF 1 "register_operand" "")) - (parallel [(set (match_dup 2) - (fix:DI (fix:SF (match_dup 4)))) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6)) - (clobber (match_scratch:SI 7 ""))]) - (set (match_operand:SI 0 "general_operand" "") - (match_dup 3))] - "TARGET_80387" - " -{ - operands[2] = gen_reg_rtx (DImode); - operands[3] = gen_lowpart (SImode, operands[2]); - operands[4] = gen_reg_rtx (SFmode); - operands[5] = (rtx) assign_386_stack_local (SImode, 0); - operands[6] = (rtx) assign_386_stack_local (SImode, 1); -}") - -;; Signed conversion to DImode. - -(define_expand "fix_truncxfdi2" - [(set (match_dup 2) - (match_operand:XF 1 "register_operand" "")) - (parallel [(set (match_operand:DI 0 "general_operand" "") - (fix:DI (fix:XF (match_dup 2)))) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (match_scratch:SI 5 ""))])] - "TARGET_80387" - " -{ - operands[1] = copy_to_mode_reg (XFmode, operands[1]); - operands[2] = gen_reg_rtx (XFmode); - operands[3] = (rtx) assign_386_stack_local (SImode, 0); - operands[4] = (rtx) assign_386_stack_local (SImode, 1); -}") - -(define_expand "fix_truncdfdi2" - [(set (match_dup 2) - (match_operand:DF 1 "register_operand" "")) - (parallel [(set (match_operand:DI 0 "general_operand" "") - (fix:DI (fix:DF (match_dup 2)))) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (match_scratch:SI 5 ""))])] - "TARGET_80387" - " -{ - operands[1] = copy_to_mode_reg (DFmode, operands[1]); - operands[2] = gen_reg_rtx (DFmode); - operands[3] = (rtx) assign_386_stack_local (SImode, 0); - operands[4] = (rtx) assign_386_stack_local (SImode, 1); -}") - -(define_expand "fix_truncsfdi2" - [(set (match_dup 2) - (match_operand:SF 1 "register_operand" "")) - (parallel [(set (match_operand:DI 0 "general_operand" "") - (fix:DI (fix:SF (match_dup 2)))) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (match_scratch:SI 5 ""))])] - "TARGET_80387" - " -{ - operands[1] = copy_to_mode_reg (SFmode, operands[1]); - operands[2] = gen_reg_rtx (SFmode); - operands[3] = (rtx) assign_386_stack_local (SImode, 0); - operands[4] = (rtx) assign_386_stack_local (SImode, 1); -}") - -;; These match a signed conversion of either DFmode or SFmode to DImode. - -(define_insn "" - [(set (match_operand:DI 0 "general_operand" "=rm") - (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f")))) - (clobber (match_dup 1)) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:SI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] - "TARGET_80387" - "* return output_fix_trunc (insn, operands);") - -(define_insn "" - [(set (match_operand:DI 0 "general_operand" "=rm") - (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f")))) - (clobber (match_dup 1)) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:SI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] - "TARGET_80387" - "* return output_fix_trunc (insn, operands);") - -(define_insn "" - [(set (match_operand:DI 0 "general_operand" "=rm") - (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f")))) - (clobber (match_dup 1)) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:SI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] - "TARGET_80387" - "* return output_fix_trunc (insn, operands);") - -;; Signed MODE_FLOAT conversion to SImode. - -(define_expand "fix_truncxfsi2" - [(parallel [(set (match_operand:SI 0 "general_operand" "") - (fix:SI - (fix:XF (match_operand:XF 1 "register_operand" "")))) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_scratch:SI 4 ""))])] - "TARGET_80387" - " -{ - operands[2] = (rtx) assign_386_stack_local (SImode, 0); - operands[3] = (rtx) assign_386_stack_local (SImode, 1); -}") - -(define_expand "fix_truncdfsi2" - [(parallel [(set (match_operand:SI 0 "general_operand" "") - (fix:SI - (fix:DF (match_operand:DF 1 "register_operand" "")))) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_scratch:SI 4 ""))])] - "TARGET_80387" - " -{ - operands[2] = (rtx) assign_386_stack_local (SImode, 0); - operands[3] = (rtx) assign_386_stack_local (SImode, 1); -}") - -(define_expand "fix_truncsfsi2" - [(parallel [(set (match_operand:SI 0 "general_operand" "") - (fix:SI - (fix:SF (match_operand:SF 1 "register_operand" "")))) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_scratch:SI 4 ""))])] - "TARGET_80387" - " -{ - operands[2] = (rtx) assign_386_stack_local (SImode, 0); - operands[3] = (rtx) assign_386_stack_local (SImode, 1); -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=rm") - (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f")))) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:SI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] - "TARGET_80387" - "* return output_fix_trunc (insn, operands);") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=rm") - (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f")))) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:SI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] - "TARGET_80387" - "* return output_fix_trunc (insn, operands);") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=rm") - (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f")))) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:SI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] - "TARGET_80387" - "* return output_fix_trunc (insn, operands);") - -;; Conversion between fixed point and floating point. -;; The actual pattern that matches these is at the end of this file. - -;; ??? Possibly represent floatunssidf2 here in gcc2. - -(define_expand "floatsisf2" - [(set (match_operand:SF 0 "register_operand" "") - (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "floatdisf2" - [(set (match_operand:SF 0 "register_operand" "") - (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "floatsidf2" - [(set (match_operand:DF 0 "register_operand" "") - (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "floatdidf2" - [(set (match_operand:DF 0 "register_operand" "") - (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "floatsixf2" - [(set (match_operand:XF 0 "register_operand" "") - (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "floatdixf2" - [(set (match_operand:XF 0 "register_operand" "") - (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -;; This will convert from SImode or DImode to MODE_FLOAT. - -(define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f") - (float:XF (match_operand:DI 1 "general_operand" "rm")))] - "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))] - "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))] - "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))] - "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") - -(define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f,f") - (float:XF (match_operand:SI 1 "general_operand" "m,!*r")))] - "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))] - "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") - -;;- add instructions - -(define_insn "adddi3" - [(set (match_operand:DI 0 "general_operand" "=&r,ro,o,&r,ro,o,&r,o,o,o") - (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,o,riF,o,or,riF,riF,o") - (match_operand:DI 2 "general_operand" "o,riF,o,0,0,0,oriF,riF,o,o"))) - (clobber (match_scratch:SI 3 "=X,X,&r,X,&r,&r,X,&r,&r,&r"))] - "" - "* -{ - rtx low[3], high[3], xops[7], temp; - - CC_STATUS_INIT; - - if (rtx_equal_p (operands[0], operands[2])) - { - temp = operands[1]; - operands[1] = operands[2]; - operands[2] = temp; - } - - split_di (operands, 3, low, high); - if (!rtx_equal_p (operands[0], operands[1])) - { - xops[0] = high[0]; - xops[1] = low[0]; - xops[2] = high[1]; - xops[3] = low[1]; - - if (GET_CODE (operands[0]) != MEM) - { - output_asm_insn (AS2 (mov%L1,%3,%1), xops); - output_asm_insn (AS2 (mov%L0,%2,%0), xops); - } - else - { - xops[4] = high[2]; - xops[5] = low[2]; - xops[6] = operands[3]; - output_asm_insn (AS2 (mov%L6,%3,%6), xops); - output_asm_insn (AS2 (add%L6,%5,%6), xops); - output_asm_insn (AS2 (mov%L1,%6,%1), xops); - output_asm_insn (AS2 (mov%L6,%2,%6), xops); - output_asm_insn (AS2 (adc%L6,%4,%6), xops); - output_asm_insn (AS2 (mov%L0,%6,%0), xops); - RET; - } - } - - if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG) - { - xops[0] = high[0]; - xops[1] = low[0]; - xops[2] = high[2]; - xops[3] = low[2]; - xops[4] = operands[3]; - - output_asm_insn (AS2 (mov%L4,%3,%4), xops); - output_asm_insn (AS2 (add%L1,%4,%1), xops); - output_asm_insn (AS2 (mov%L4,%2,%4), xops); - output_asm_insn (AS2 (adc%L0,%4,%0), xops); - } - - else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0) - { - output_asm_insn (AS2 (add%L0,%2,%0), low); - output_asm_insn (AS2 (adc%L0,%2,%0), high); - } - - else - output_asm_insn (AS2 (add%L0,%2,%0), high); - - RET; -}") - -;; On a 486, it is faster to do movl/addl than to do a single leal if -;; operands[1] and operands[2] are both registers. - -(define_insn "addsi3" - [(set (match_operand:SI 0 "general_operand" "=?r,rm,r") - (plus:SI (match_operand:SI 1 "general_operand" "%r,0,0") - (match_operand:SI 2 "general_operand" "ri,ri,rm")))] - "" - "* -{ - if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1])) - { - if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2])) - return AS2 (add%L0,%1,%0); - - if (operands[2] == stack_pointer_rtx) - { - rtx temp; - - temp = operands[1]; - operands[1] = operands[2]; - operands[2] = temp; - } - - if (operands[2] != stack_pointer_rtx) - { - CC_STATUS_INIT; - operands[1] = SET_SRC (PATTERN (insn)); - return AS2 (lea%L0,%a1,%0); - } - - output_asm_insn (AS2 (mov%L0,%1,%0), operands); - } - - if (operands[2] == const1_rtx) - return AS1 (inc%L0,%0); - - if (operands[2] == constm1_rtx) - return AS1 (dec%L0,%0); - - return AS2 (add%L0,%2,%0); -}") - -;; ??? `lea' here, for three operand add? If leaw is used, only %bx, -;; %si and %di can appear in SET_SRC, and output_asm_insn might not be -;; able to handle the operand. But leal always works? - -(define_insn "addhi3" - [(set (match_operand:HI 0 "general_operand" "=rm,r") - (plus:HI (match_operand:HI 1 "general_operand" "%0,0") - (match_operand:HI 2 "general_operand" "ri,rm")))] - "" - "* -{ - /* ??? what about offsettable memory references? */ - if (QI_REG_P (operands[0]) - && GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) & 0xff) == 0) - { - int byteval = (INTVAL (operands[2]) >> 8) & 0xff; - CC_STATUS_INIT; - - if (byteval == 1) - return AS1 (inc%B0,%h0); - else if (byteval == 255) - return AS1 (dec%B0,%h0); - - operands[2] = GEN_INT (byteval); - return AS2 (add%B0,%2,%h0); - } - - if (operands[2] == const1_rtx) - return AS1 (inc%W0,%0); - - if (operands[2] == constm1_rtx - || (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) == 65535)) - return AS1 (dec%W0,%0); - - return AS2 (add%W0,%2,%0); -}") - -(define_insn "addqi3" - [(set (match_operand:QI 0 "general_operand" "=qm,q") - (plus:QI (match_operand:QI 1 "general_operand" "%0,0") - (match_operand:QI 2 "general_operand" "qn,qmn")))] - "" - "* -{ - if (operands[2] == const1_rtx) - return AS1 (inc%B0,%0); - - if (operands[2] == constm1_rtx - || (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) == 255)) - return AS1 (dec%B0,%0); - - return AS2 (add%B0,%2,%0); -}") - -;Lennart Augustsson -;says this pattern just makes slower code: -; pushl %ebp -; addl $-80,(%esp) -;instead of -; leal -80(%ebp),%eax -; pushl %eax -; -;(define_insn "" -; [(set (match_operand:SI 0 "push_operand" "=<") -; (plus:SI (match_operand:SI 1 "general_operand" "%r") -; (match_operand:SI 2 "general_operand" "ri")))] -; "" -; "* -;{ -; rtx xops[4]; -; xops[0] = operands[0]; -; xops[1] = operands[1]; -; xops[2] = operands[2]; -; xops[3] = gen_rtx (MEM, SImode, stack_pointer_rtx); -; output_asm_insn (\"push%z1 %1\", xops); -; output_asm_insn (AS2 (add%z3,%2,%3), xops); -; RET; -;}") - -;; addsi3 is faster, so put this after. - -(define_insn "movsi_lea" - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operand:QI 1 "address_operand" "p"))] - "" - "* -{ - CC_STATUS_INIT; - /* Adding a constant to a register is faster with an add. */ - /* ??? can this ever happen? */ - if (GET_CODE (operands[1]) == PLUS - && GET_CODE (XEXP (operands[1], 1)) == CONST_INT - && rtx_equal_p (operands[0], XEXP (operands[1], 0))) - { - operands[1] = XEXP (operands[1], 1); - - if (operands[1] == const1_rtx) - return AS1 (inc%L0,%0); - - if (operands[1] == constm1_rtx) - return AS1 (dec%L0,%0); - - return AS2 (add%L0,%1,%0); - } - return AS2 (lea%L0,%a1,%0); -}") - -;; The patterns that match these are at the end of this file. - -(define_expand "addxf3" - [(set (match_operand:XF 0 "register_operand" "") - (plus:XF (match_operand:XF 1 "nonimmediate_operand" "") - (match_operand:XF 2 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "adddf3" - [(set (match_operand:DF 0 "register_operand" "") - (plus:DF (match_operand:DF 1 "nonimmediate_operand" "") - (match_operand:DF 2 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "addsf3" - [(set (match_operand:SF 0 "register_operand" "") - (plus:SF (match_operand:SF 1 "nonimmediate_operand" "") - (match_operand:SF 2 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -;;- subtract instructions - -(define_insn "subdi3" - [(set (match_operand:DI 0 "general_operand" "=&r,ro,&r,o,o") - (minus:DI (match_operand:DI 1 "general_operand" "0,0,roiF,riF,o") - (match_operand:DI 2 "general_operand" "o,riF,roiF,riF,o"))) - (clobber (match_scratch:SI 3 "=X,X,X,&r,&r"))] - "" - "* -{ - rtx low[3], high[3], xops[7]; - - CC_STATUS_INIT; - - split_di (operands, 3, low, high); - - if (!rtx_equal_p (operands[0], operands[1])) - { - xops[0] = high[0]; - xops[1] = low[0]; - xops[2] = high[1]; - xops[3] = low[1]; - - if (GET_CODE (operands[0]) != MEM) - { - output_asm_insn (AS2 (mov%L1,%3,%1), xops); - output_asm_insn (AS2 (mov%L0,%2,%0), xops); - } - else - { - xops[4] = high[2]; - xops[5] = low[2]; - xops[6] = operands[3]; - output_asm_insn (AS2 (mov%L6,%3,%6), xops); - output_asm_insn (AS2 (sub%L6,%5,%6), xops); - output_asm_insn (AS2 (mov%L1,%6,%1), xops); - output_asm_insn (AS2 (mov%L6,%2,%6), xops); - output_asm_insn (AS2 (sbb%L6,%4,%6), xops); - output_asm_insn (AS2 (mov%L0,%6,%0), xops); - RET; - } - } - - if (GET_CODE (operands[3]) == REG) - { - xops[0] = high[0]; - xops[1] = low[0]; - xops[2] = high[2]; - xops[3] = low[2]; - xops[4] = operands[3]; - - output_asm_insn (AS2 (mov%L4,%3,%4), xops); - output_asm_insn (AS2 (sub%L1,%4,%1), xops); - output_asm_insn (AS2 (mov%L4,%2,%4), xops); - output_asm_insn (AS2 (sbb%L0,%4,%0), xops); - } - - else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0) - { - output_asm_insn (AS2 (sub%L0,%2,%0), low); - output_asm_insn (AS2 (sbb%L0,%2,%0), high); - } - - else - output_asm_insn (AS2 (sub%L0,%2,%0), high); - - RET; -}") - -(define_insn "subsi3" - [(set (match_operand:SI 0 "general_operand" "=rm,r") - (minus:SI (match_operand:SI 1 "general_operand" "0,0") - (match_operand:SI 2 "general_operand" "ri,rm")))] - "" - "* return AS2 (sub%L0,%2,%0);") - -(define_insn "subhi3" - [(set (match_operand:HI 0 "general_operand" "=rm,r") - (minus:HI (match_operand:HI 1 "general_operand" "0,0") - (match_operand:HI 2 "general_operand" "ri,rm")))] - "" - "* return AS2 (sub%W0,%2,%0);") - -(define_insn "subqi3" - [(set (match_operand:QI 0 "general_operand" "=qm,q") - (minus:QI (match_operand:QI 1 "general_operand" "0,0") - (match_operand:QI 2 "general_operand" "qn,qmn")))] - "" - "* return AS2 (sub%B0,%2,%0);") - -;; The patterns that match these are at the end of this file. - -(define_expand "subxf3" - [(set (match_operand:XF 0 "register_operand" "") - (minus:XF (match_operand:XF 1 "nonimmediate_operand" "") - (match_operand:XF 2 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "subdf3" - [(set (match_operand:DF 0 "register_operand" "") - (minus:DF (match_operand:DF 1 "nonimmediate_operand" "") - (match_operand:DF 2 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "subsf3" - [(set (match_operand:SF 0 "register_operand" "") - (minus:SF (match_operand:SF 1 "nonimmediate_operand" "") - (match_operand:SF 2 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -;;- multiply instructions - -;(define_insn "mulqi3" -; [(set (match_operand:QI 0 "general_operand" "=a") -; (mult:QI (match_operand:QI 1 "general_operand" "%0") -; (match_operand:QI 2 "general_operand" "qm")))] -; "" -; "imul%B0 %2,%0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=r") - (mult:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "r")))] - "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80" - "* return AS2 (imul%W0,%2,%0);") - -(define_insn "mulhi3" - [(set (match_operand:HI 0 "general_operand" "=r,r") - (mult:HI (match_operand:HI 1 "general_operand" "%0,rm") - (match_operand:HI 2 "general_operand" "g,i")))] - "" - "* -{ - if (GET_CODE (operands[1]) == REG - && REGNO (operands[1]) == REGNO (operands[0]) - && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG)) - /* Assembler has weird restrictions. */ - return AS2 (imul%W0,%2,%0); - return AS3 (imul%W0,%2,%1,%0); -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=r") - (mult:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "r")))] - "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80" - "* return AS2 (imul%L0,%2,%0);") - -(define_insn "mulsi3" - [(set (match_operand:SI 0 "general_operand" "=r,r") - (mult:SI (match_operand:SI 1 "general_operand" "%0,rm") - (match_operand:SI 2 "general_operand" "g,i")))] - "" - "* -{ - if (GET_CODE (operands[1]) == REG - && REGNO (operands[1]) == REGNO (operands[0]) - && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG)) - /* Assembler has weird restrictions. */ - return AS2 (imul%L0,%2,%0); - return AS3 (imul%L0,%2,%1,%0); -}") - -(define_insn "umulqihi3" - [(set (match_operand:HI 0 "general_operand" "=a") - (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) - (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))] - "" - "mul%B0 %2") - -(define_insn "mulqihi3" - [(set (match_operand:HI 0 "general_operand" "=a") - (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) - (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))] - "" - "imul%B0 %2") - -(define_insn "umulsidi3" - [(set (match_operand:DI 0 "register_operand" "=A") - (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) - (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))] - "TARGET_WIDE_MULTIPLY" - "mul%L0 %2") - -(define_insn "mulsidi3" - [(set (match_operand:DI 0 "register_operand" "=A") - (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0")) - (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))] - "TARGET_WIDE_MULTIPLY" - "imul%L0 %2") - -(define_insn "umulsi3_highpart" - [(set (match_operand:SI 0 "register_operand" "=d") - (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a")) - (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))) - (const_int 32)))) - (clobber (match_scratch:SI 3 "=a"))] - "TARGET_WIDE_MULTIPLY" - "mul%L0 %2") - -(define_insn "smulsi3_highpart" - [(set (match_operand:SI 0 "register_operand" "=d") - (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a")) - (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))) - (const_int 32)))) - (clobber (match_scratch:SI 3 "=a"))] - "TARGET_WIDE_MULTIPLY" - "imul%L0 %2") - -;; The patterns that match these are at the end of this file. - -(define_expand "mulxf3" - [(set (match_operand:XF 0 "register_operand" "") - (mult:XF (match_operand:XF 1 "nonimmediate_operand" "") - (match_operand:XF 2 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "muldf3" - [(set (match_operand:DF 0 "register_operand" "") - (mult:DF (match_operand:DF 1 "nonimmediate_operand" "") - (match_operand:DF 2 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "mulsf3" - [(set (match_operand:SF 0 "register_operand" "") - (mult:SF (match_operand:SF 1 "nonimmediate_operand" "") - (match_operand:SF 2 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -;;- divide instructions - -(define_insn "divqi3" - [(set (match_operand:QI 0 "general_operand" "=a") - (div:QI (match_operand:HI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "qm")))] - "" - "idiv%B0 %2") - -(define_insn "udivqi3" - [(set (match_operand:QI 0 "general_operand" "=a") - (udiv:QI (match_operand:HI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "qm")))] - "" - "div%B0 %2") - -;; The patterns that match these are at the end of this file. - -(define_expand "divxf3" - [(set (match_operand:XF 0 "register_operand" "") - (div:XF (match_operand:XF 1 "nonimmediate_operand" "") - (match_operand:XF 2 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "divdf3" - [(set (match_operand:DF 0 "register_operand" "") - (div:DF (match_operand:DF 1 "nonimmediate_operand" "") - (match_operand:DF 2 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "divsf3" - [(set (match_operand:SF 0 "register_operand" "") - (div:SF (match_operand:SF 1 "nonimmediate_operand" "") - (match_operand:SF 2 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -;; Remainder instructions. - -(define_insn "divmodsi4" - [(set (match_operand:SI 0 "register_operand" "=a") - (div:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "rm"))) - (set (match_operand:SI 3 "register_operand" "=&d") - (mod:SI (match_dup 1) (match_dup 2)))] - "" - "* -{ -#ifdef INTEL_SYNTAX - output_asm_insn (\"cdq\", operands); -#else - output_asm_insn (\"cltd\", operands); -#endif - return AS1 (idiv%L0,%2); -}") - -(define_insn "divmodhi4" - [(set (match_operand:HI 0 "register_operand" "=a") - (div:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "general_operand" "rm"))) - (set (match_operand:HI 3 "register_operand" "=&d") - (mod:HI (match_dup 1) (match_dup 2)))] - "" - "cwtd\;idiv%W0 %2") - -;; ??? Can we make gcc zero extend operand[0]? -(define_insn "udivmodsi4" - [(set (match_operand:SI 0 "register_operand" "=a") - (udiv:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "rm"))) - (set (match_operand:SI 3 "register_operand" "=&d") - (umod:SI (match_dup 1) (match_dup 2)))] - "" - "* -{ - output_asm_insn (AS2 (xor%L3,%3,%3), operands); - return AS1 (div%L0,%2); -}") - -;; ??? Can we make gcc zero extend operand[0]? -(define_insn "udivmodhi4" - [(set (match_operand:HI 0 "register_operand" "=a") - (udiv:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "general_operand" "rm"))) - (set (match_operand:HI 3 "register_operand" "=&d") - (umod:HI (match_dup 1) (match_dup 2)))] - "" - "* -{ - output_asm_insn (AS2 (xor%W0,%3,%3), operands); - return AS1 (div%W0,%2); -}") - -/* -;;this should be a valid double division which we may want to add - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=a") - (udiv:DI (match_operand:DI 1 "register_operand" "a") - (match_operand:SI 2 "general_operand" "rm"))) - (set (match_operand:SI 3 "register_operand" "=d") - (umod:SI (match_dup 1) (match_dup 2)))] - "" - "div%L0 %2,%0") -*/ - -;;- and instructions - -;; On i386, -;; movzbl %bl,%ebx -;; is faster than -;; andl $255,%ebx -;; -;; but if the reg is %eax, then the "andl" is faster. -;; -;; On i486, the "andl" is always faster than the "movzbl". -;; -;; On both i386 and i486, a three operand AND is as fast with movzbl or -;; movzwl as with andl, if operands[0] != operands[1]. - -;; The `r' in `rm' for operand 3 looks redundant, but it causes -;; optional reloads to be generated if op 3 is a pseudo in a stack slot. - -;; ??? What if we only change one byte of an offsettable memory reference? -(define_insn "andsi3" - [(set (match_operand:SI 0 "general_operand" "=r,r,rm,r") - (and:SI (match_operand:SI 1 "general_operand" "%rm,qm,0,0") - (match_operand:SI 2 "general_operand" "L,K,ri,rm")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT - && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) - { - if (INTVAL (operands[2]) == 0xffff && REG_P (operands[0]) - && (! REG_P (operands[1]) - || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0) - && (TARGET_386 || ! rtx_equal_p (operands[0], operands[1]))) - { - /* ??? tege: Should forget CC_STATUS only if we clobber a - remembered operand. Fix that later. */ - CC_STATUS_INIT; -#ifdef INTEL_SYNTAX - return AS2 (movzx,%w1,%0); -#else - return AS2 (movz%W0%L0,%w1,%0); -#endif - } - - if (INTVAL (operands[2]) == 0xff && REG_P (operands[0]) - && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1])) - && (! REG_P (operands[1]) - || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0) - && (TARGET_386 || ! rtx_equal_p (operands[0], operands[1]))) - { - /* ??? tege: Should forget CC_STATUS only if we clobber a - remembered operand. Fix that later. */ - CC_STATUS_INIT; -#ifdef INTEL_SYNTAX - return AS2 (movzx,%b1,%0); -#else - return AS2 (movz%B0%L0,%b1,%0); -#endif - } - - if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff) == 0) - { - CC_STATUS_INIT; - - if (INTVAL (operands[2]) == 0xffffff00) - { - operands[2] = const0_rtx; - return AS2 (mov%B0,%2,%b0); - } - - operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); - return AS2 (and%B0,%2,%b0); - } - - if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff00) == 0) - { - CC_STATUS_INIT; - - if (INTVAL (operands[2]) == 0xffff00ff) - { - operands[2] = const0_rtx; - return AS2 (mov%B0,%2,%h0); - } - - operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); - return AS2 (and%B0,%2,%h0); - } - - if (GET_CODE (operands[0]) == MEM && INTVAL (operands[2]) == 0xffff0000) - { - operands[2] = const0_rtx; - return AS2 (mov%W0,%2,%w0); - } - } - - return AS2 (and%L0,%2,%0); -}") - -(define_insn "andhi3" - [(set (match_operand:HI 0 "general_operand" "=rm,r") - (and:HI (match_operand:HI 1 "general_operand" "%0,0") - (match_operand:HI 2 "general_operand" "ri,rm")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT - && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) - { - /* Can we ignore the upper byte? */ - if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) - && (INTVAL (operands[2]) & 0xff00) == 0xff00) - { - CC_STATUS_INIT; - - if ((INTVAL (operands[2]) & 0xff) == 0) - { - operands[2] = const0_rtx; - return AS2 (mov%B0,%2,%b0); - } - - operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); - return AS2 (and%B0,%2,%b0); - } - - /* Can we ignore the lower byte? */ - /* ??? what about offsettable memory references? */ - if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff) - { - CC_STATUS_INIT; - - if ((INTVAL (operands[2]) & 0xff00) == 0) - { - operands[2] = const0_rtx; - return AS2 (mov%B0,%2,%h0); - } - - operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); - return AS2 (and%B0,%2,%h0); - } - } - - return AS2 (and%W0,%2,%0); -}") - -(define_insn "andqi3" - [(set (match_operand:QI 0 "general_operand" "=qm,q") - (and:QI (match_operand:QI 1 "general_operand" "%0,0") - (match_operand:QI 2 "general_operand" "qn,qmn")))] - "" - "* return AS2 (and%B0,%2,%0);") - -/* I am nervous about these two.. add them later.. -;I presume this means that we have something in say op0= eax which is small -;and we want to and it with memory so we can do this by just an -;andb m,%al and have success. -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=r") - (and:SI (zero_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "rm")) - (match_operand:SI 2 "general_operand" "0")))] - "GET_CODE (operands[2]) == CONST_INT - && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))" - "and%W0 %1,%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=q") - (and:SI - (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")) - (match_operand:SI 2 "general_operand" "0")))] - "GET_CODE (operands[2]) == CONST_INT - && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))" - "and%L0 %1,%0") - -*/ - -;;- Bit set (inclusive or) instructions - -;; ??? What if we only change one byte of an offsettable memory reference? -(define_insn "iorsi3" - [(set (match_operand:SI 0 "general_operand" "=rm,r") - (ior:SI (match_operand:SI 1 "general_operand" "%0,0") - (match_operand:SI 2 "general_operand" "ri,rm")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT - && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) - { - if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) - && (INTVAL (operands[2]) & ~0xff) == 0) - { - CC_STATUS_INIT; - - if (INTVAL (operands[2]) == 0xff) - return AS2 (mov%B0,%2,%b0); - - return AS2 (or%B0,%2,%b0); - } - - if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0) - { - CC_STATUS_INIT; - operands[2] = GEN_INT (INTVAL (operands[2]) >> 8); - - if (INTVAL (operands[2]) == 0xff) - return AS2 (mov%B0,%2,%h0); - - return AS2 (or%B0,%2,%h0); - } - } - - return AS2 (or%L0,%2,%0); -}") - -(define_insn "iorhi3" - [(set (match_operand:HI 0 "general_operand" "=rm,r") - (ior:HI (match_operand:HI 1 "general_operand" "%0,0") - (match_operand:HI 2 "general_operand" "ri,rm")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT - && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) - { - /* Can we ignore the upper byte? */ - if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) - && (INTVAL (operands[2]) & 0xff00) == 0) - { - CC_STATUS_INIT; - if (INTVAL (operands[2]) & 0xffff0000) - operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); - - if (INTVAL (operands[2]) == 0xff) - return AS2 (mov%B0,%2,%b0); - - return AS2 (or%B0,%2,%b0); - } - - /* Can we ignore the lower byte? */ - /* ??? what about offsettable memory references? */ - if (QI_REG_P (operands[0]) - && (INTVAL (operands[2]) & 0xff) == 0) - { - CC_STATUS_INIT; - operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); - - if (INTVAL (operands[2]) == 0xff) - return AS2 (mov%B0,%2,%h0); - - return AS2 (or%B0,%2,%h0); - } - } - - return AS2 (or%W0,%2,%0); -}") - -(define_insn "iorqi3" - [(set (match_operand:QI 0 "general_operand" "=qm,q") - (ior:QI (match_operand:QI 1 "general_operand" "%0,0") - (match_operand:QI 2 "general_operand" "qn,qmn")))] - "" - "* return AS2 (or%B0,%2,%0);") - -;;- xor instructions - -;; ??? What if we only change one byte of an offsettable memory reference? -(define_insn "xorsi3" - [(set (match_operand:SI 0 "general_operand" "=rm,r") - (xor:SI (match_operand:SI 1 "general_operand" "%0,0") - (match_operand:SI 2 "general_operand" "ri,rm")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT - && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) - { - if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) - && (INTVAL (operands[2]) & ~0xff) == 0) - { - CC_STATUS_INIT; - - if (INTVAL (operands[2]) == 0xff) - return AS1 (not%B0,%b0); - - return AS2 (xor%B0,%2,%b0); - } - - if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0) - { - CC_STATUS_INIT; - operands[2] = GEN_INT (INTVAL (operands[2]) >> 8); - - if (INTVAL (operands[2]) == 0xff) - return AS1 (not%B0,%h0); - - return AS2 (xor%B0,%2,%h0); - } - } - - return AS2 (xor%L0,%2,%0); -}") - -(define_insn "xorhi3" - [(set (match_operand:HI 0 "general_operand" "=rm,r") - (xor:HI (match_operand:HI 1 "general_operand" "%0,0") - (match_operand:HI 2 "general_operand" "ri,rm")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT - && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) - { - /* Can we ignore the upper byte? */ - if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) - && (INTVAL (operands[2]) & 0xff00) == 0) - { - CC_STATUS_INIT; - if (INTVAL (operands[2]) & 0xffff0000) - operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); - - if (INTVAL (operands[2]) == 0xff) - return AS1 (not%B0,%b0); - - return AS2 (xor%B0,%2,%b0); - } - - /* Can we ignore the lower byte? */ - /* ??? what about offsettable memory references? */ - if (QI_REG_P (operands[0]) - && (INTVAL (operands[2]) & 0xff) == 0) - { - CC_STATUS_INIT; - operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); - - if (INTVAL (operands[2]) == 0xff) - return AS1 (not%B0,%h0); - - return AS2 (xor%B0,%2,%h0); - } - } - - return AS2 (xor%W0,%2,%0); -}") - -(define_insn "xorqi3" - [(set (match_operand:QI 0 "general_operand" "=qm,q") - (xor:QI (match_operand:QI 1 "general_operand" "%0,0") - (match_operand:QI 2 "general_operand" "qn,qm")))] - "" - "* return AS2 (xor%B0,%2,%0);") - -;;- negation instructions - -(define_insn "negdi2" - [(set (match_operand:DI 0 "general_operand" "=&ro") - (neg:DI (match_operand:DI 1 "general_operand" "0")))] - "" - "* -{ - rtx xops[2], low[1], high[1]; - - CC_STATUS_INIT; - - split_di (operands, 1, low, high); - xops[0] = const0_rtx; - xops[1] = high[0]; - - output_asm_insn (AS1 (neg%L0,%0), low); - output_asm_insn (AS2 (adc%L1,%0,%1), xops); - output_asm_insn (AS1 (neg%L0,%0), high); - RET; -}") - -(define_insn "negsi2" - [(set (match_operand:SI 0 "general_operand" "=rm") - (neg:SI (match_operand:SI 1 "general_operand" "0")))] - "" - "neg%L0 %0") - -(define_insn "neghi2" - [(set (match_operand:HI 0 "general_operand" "=rm") - (neg:HI (match_operand:HI 1 "general_operand" "0")))] - "" - "neg%W0 %0") - -(define_insn "negqi2" - [(set (match_operand:QI 0 "general_operand" "=qm") - (neg:QI (match_operand:QI 1 "general_operand" "0")))] - "" - "neg%B0 %0") - -(define_insn "negsf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (match_operand:SF 1 "general_operand" "0")))] - "TARGET_80387" - "fchs") - -(define_insn "negdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (match_operand:DF 1 "general_operand" "0")))] - "TARGET_80387" - "fchs") - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))] - "TARGET_80387" - "fchs") - -(define_insn "negxf2" - [(set (match_operand:XF 0 "register_operand" "=f") - (neg:XF (match_operand:XF 1 "general_operand" "0")))] - "TARGET_80387" - "fchs") - -(define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f") - (neg:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))] - "TARGET_80387" - "fchs") - -;; Absolute value instructions - -(define_insn "abssf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (abs:SF (match_operand:SF 1 "general_operand" "0")))] - "TARGET_80387" - "fabs") - -(define_insn "absdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (abs:DF (match_operand:DF 1 "general_operand" "0")))] - "TARGET_80387" - "fabs") - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (abs:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))] - "TARGET_80387" - "fabs") - -(define_insn "absxf2" - [(set (match_operand:XF 0 "register_operand" "=f") - (abs:XF (match_operand:XF 1 "general_operand" "0")))] - "TARGET_80387" - "fabs") - -(define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f") - (abs:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))] - "TARGET_80387" - "fabs") - -(define_insn "sqrtsf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (sqrt:SF (match_operand:SF 1 "general_operand" "0")))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fsqrt") - -(define_insn "sqrtdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (sqrt:DF (match_operand:DF 1 "general_operand" "0")))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fsqrt") - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (sqrt:DF (float_extend:DF - (match_operand:SF 1 "general_operand" "0"))))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fsqrt") - -(define_insn "sqrtxf2" - [(set (match_operand:XF 0 "register_operand" "=f") - (sqrt:XF (match_operand:XF 1 "general_operand" "0")))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fsqrt") - -(define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f") - (sqrt:XF (float_extend:XF - (match_operand:DF 1 "general_operand" "0"))))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fsqrt") - -(define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f") - (sqrt:XF (float_extend:XF - (match_operand:SF 1 "general_operand" "0"))))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fsqrt") - -(define_insn "sindf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fsin") - -(define_insn "sinsf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fsin") - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (unspec:DF [(float_extend:DF - (match_operand:SF 1 "register_operand" "0"))] 1))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fsin") - -(define_insn "sinxf2" - [(set (match_operand:XF 0 "register_operand" "=f") - (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fsin") - -(define_insn "cosdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fcos") - -(define_insn "cossf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fcos") - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (unspec:DF [(float_extend:DF - (match_operand:SF 1 "register_operand" "0"))] 2))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fcos") - -(define_insn "cosxf2" - [(set (match_operand:XF 0 "register_operand" "=f") - (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " - "fcos") - -;;- one complement instructions - -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "general_operand" "=rm") - (not:SI (match_operand:SI 1 "general_operand" "0")))] - "" - "not%L0 %0") - -(define_insn "one_cmplhi2" - [(set (match_operand:HI 0 "general_operand" "=rm") - (not:HI (match_operand:HI 1 "general_operand" "0")))] - "" - "not%W0 %0") - -(define_insn "one_cmplqi2" - [(set (match_operand:QI 0 "general_operand" "=qm") - (not:QI (match_operand:QI 1 "general_operand" "0")))] - "" - "not%B0 %0") - -;;- arithmetic shift instructions - -;; DImode shifts are implemented using the i386 "shift double" opcode, -;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count -;; is variable, then the count is in %cl and the "imm" operand is dropped -;; from the assembler input. - -;; This instruction shifts the target reg/mem as usual, but instead of -;; shifting in zeros, bits are shifted in from reg operand. If the insn -;; is a left shift double, bits are taken from the high order bits of -;; reg, else if the insn is a shift right double, bits are taken from the -;; low order bits of reg. So if %eax is "1234" and %edx is "5678", -;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". - -;; Since sh[lr]d does not change the `reg' operand, that is done -;; separately, making all shifts emit pairs of shift double and normal -;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to -;; support a 63 bit shift, each shift where the count is in a reg expands -;; to three pairs. If the overall shift is by N bits, then the first two -;; pairs shift by N / 2 and the last pair by N & 1. - -;; If the shift count is a constant, we need never emit more than one -;; shift pair, instead using moves and sign extension for counts greater -;; than 31. - -(define_expand "ashldi3" - [(set (match_operand:DI 0 "register_operand" "") - (ashift:DI (match_operand:DI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT - || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')) - { - operands[2] = copy_to_mode_reg (QImode, operands[2]); - emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1], - operands[2])); - } - else - emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2])); - - DONE; -}") - -(define_insn "ashldi3_const_int" - [(set (match_operand:DI 0 "register_operand" "=&r") - (ashift:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "const_int_operand" "J")))] - "" - "* -{ - rtx xops[4], low[1], high[1]; - - CC_STATUS_INIT; - - split_di (operands, 1, low, high); - xops[0] = operands[2]; - xops[1] = const1_rtx; - xops[2] = low[0]; - xops[3] = high[0]; - - if (INTVAL (xops[0]) > 31) - { - output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */ - output_asm_insn (AS2 (xor%L2,%2,%2), xops); - - if (INTVAL (xops[0]) > 32) - { - xops[0] = GEN_INT (INTVAL (xops[0]) - 32); - output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */ - } - } - else - { - output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops); - output_asm_insn (AS2 (sal%L2,%0,%2), xops); - } - RET; -}") - -(define_insn "ashldi3_non_const_int" - [(set (match_operand:DI 0 "register_operand" "=&r") - (ashift:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "register_operand" "c"))) - (clobber (match_dup 2))] - "" - "* -{ - rtx xops[4], low[1], high[1]; - - CC_STATUS_INIT; - - split_di (operands, 1, low, high); - xops[0] = operands[2]; - xops[1] = const1_rtx; - xops[2] = low[0]; - xops[3] = high[0]; - - output_asm_insn (AS2 (ror%B0,%1,%0), xops); /* shift count / 2 */ - - output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops); - output_asm_insn (AS2 (sal%L2,%0,%2), xops); - output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops); - output_asm_insn (AS2 (sal%L2,%0,%2), xops); - - xops[1] = GEN_INT (7); /* shift count & 1 */ - - output_asm_insn (AS2 (shr%B0,%1,%0), xops); - - output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops); - output_asm_insn (AS2 (sal%L2,%0,%2), xops); - - RET; -}") - -;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg" -;; On i486, movl/sall appears slightly faster than leal, but the leal -;; is smaller - use leal for now unless the shift count is 1. - -(define_insn "ashlsi3" - [(set (match_operand:SI 0 "general_operand" "=r,rm") - (ashift:SI (match_operand:SI 1 "general_operand" "r,0") - (match_operand:SI 2 "nonmemory_operand" "M,cI")))] - "" - "* -{ - if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1])) - { - if (!TARGET_386 && INTVAL (operands[2]) == 1) - { - output_asm_insn (AS2 (mov%L0,%1,%0), operands); - return AS2 (add%L0,%1,%0); - } - else - { - CC_STATUS_INIT; - - if (operands[1] == stack_pointer_rtx) - { - output_asm_insn (AS2 (mov%L0,%1,%0), operands); - operands[1] = operands[0]; - } - operands[1] = gen_rtx (MULT, SImode, operands[1], - GEN_INT (1 << INTVAL (operands[2]))); - return AS2 (lea%L0,%a1,%0); - } - } - - if (REG_P (operands[2])) - return AS2 (sal%L0,%b2,%0); - - if (REG_P (operands[0]) && operands[2] == const1_rtx) - return AS2 (add%L0,%0,%0); - - return AS2 (sal%L0,%2,%0); -}") - -(define_insn "ashlhi3" - [(set (match_operand:HI 0 "general_operand" "=rm") - (ashift:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (sal%W0,%b2,%0); - - if (REG_P (operands[0]) && operands[2] == const1_rtx) - return AS2 (add%W0,%0,%0); - - return AS2 (sal%W0,%2,%0); -}") - -(define_insn "ashlqi3" - [(set (match_operand:QI 0 "general_operand" "=qm") - (ashift:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (sal%B0,%b2,%0); - - if (REG_P (operands[0]) && operands[2] == const1_rtx) - return AS2 (add%B0,%0,%0); - - return AS2 (sal%B0,%2,%0); -}") - -;; See comment above `ashldi3' about how this works. - -(define_expand "ashrdi3" - [(set (match_operand:DI 0 "register_operand" "") - (ashiftrt:DI (match_operand:DI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT - || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')) - { - operands[2] = copy_to_mode_reg (QImode, operands[2]); - emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1], - operands[2])); - } - else - emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2])); - - DONE; -}") - -(define_insn "ashrdi3_const_int" - [(set (match_operand:DI 0 "register_operand" "=&r") - (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "const_int_operand" "J")))] - "" - "* -{ - rtx xops[4], low[1], high[1]; - - CC_STATUS_INIT; - - split_di (operands, 1, low, high); - xops[0] = operands[2]; - xops[1] = const1_rtx; - xops[2] = low[0]; - xops[3] = high[0]; - - if (INTVAL (xops[0]) > 31) - { - xops[1] = GEN_INT (31); - output_asm_insn (AS2 (mov%L2,%3,%2), xops); - output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */ - - if (INTVAL (xops[0]) > 32) - { - xops[0] = GEN_INT (INTVAL (xops[0]) - 32); - output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */ - } - } - else - { - output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops); - output_asm_insn (AS2 (sar%L3,%0,%3), xops); - } - - RET; -}") - -(define_insn "ashrdi3_non_const_int" - [(set (match_operand:DI 0 "register_operand" "=&r") - (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "register_operand" "c"))) - (clobber (match_dup 2))] - "" - "* -{ - rtx xops[4], low[1], high[1]; - - CC_STATUS_INIT; - - split_di (operands, 1, low, high); - xops[0] = operands[2]; - xops[1] = const1_rtx; - xops[2] = low[0]; - xops[3] = high[0]; - - output_asm_insn (AS2 (ror%B0,%1,%0), xops); /* shift count / 2 */ - - output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops); - output_asm_insn (AS2 (sar%L3,%0,%3), xops); - output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops); - output_asm_insn (AS2 (sar%L3,%0,%3), xops); - - xops[1] = GEN_INT (7); /* shift count & 1 */ - - output_asm_insn (AS2 (shr%B0,%1,%0), xops); - - output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops); - output_asm_insn (AS2 (sar%L3,%0,%3), xops); - - RET; -}") - -(define_insn "ashrsi3" - [(set (match_operand:SI 0 "general_operand" "=rm") - (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (sar%L0,%b2,%0); - else - return AS2 (sar%L0,%2,%0); -}") - -(define_insn "ashrhi3" - [(set (match_operand:HI 0 "general_operand" "=rm") - (ashiftrt:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (sar%W0,%b2,%0); - else - return AS2 (sar%W0,%2,%0); -}") - -(define_insn "ashrqi3" - [(set (match_operand:QI 0 "general_operand" "=qm") - (ashiftrt:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (sar%B0,%b2,%0); - else - return AS2 (sar%B0,%2,%0); -}") - -;;- logical shift instructions - -;; See comment above `ashldi3' about how this works. - -(define_expand "lshrdi3" - [(set (match_operand:DI 0 "register_operand" "") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT - || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')) - { - operands[2] = copy_to_mode_reg (QImode, operands[2]); - emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1], - operands[2])); - } - else - emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2])); - - DONE; -}") - -(define_insn "lshrdi3_const_int" - [(set (match_operand:DI 0 "register_operand" "=&r") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "const_int_operand" "J")))] - "" - "* -{ - rtx xops[4], low[1], high[1]; - - CC_STATUS_INIT; - - split_di (operands, 1, low, high); - xops[0] = operands[2]; - xops[1] = const1_rtx; - xops[2] = low[0]; - xops[3] = high[0]; - - if (INTVAL (xops[0]) > 31) - { - output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */ - output_asm_insn (AS2 (xor%L3,%3,%3), xops); - - if (INTVAL (xops[0]) > 32) - { - xops[0] = GEN_INT (INTVAL (xops[0]) - 32); - output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */ - } - } - else - { - output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops); - output_asm_insn (AS2 (shr%L3,%0,%3), xops); - } - - RET; -}") - -(define_insn "lshrdi3_non_const_int" - [(set (match_operand:DI 0 "register_operand" "=&r") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "register_operand" "c"))) - (clobber (match_dup 2))] - "" - "* -{ - rtx xops[4], low[1], high[1]; - - CC_STATUS_INIT; - - split_di (operands, 1, low, high); - xops[0] = operands[2]; - xops[1] = const1_rtx; - xops[2] = low[0]; - xops[3] = high[0]; - - output_asm_insn (AS2 (ror%B0,%1,%0), xops); /* shift count / 2 */ - - output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops); - output_asm_insn (AS2 (shr%L3,%0,%3), xops); - output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops); - output_asm_insn (AS2 (shr%L3,%0,%3), xops); - - xops[1] = GEN_INT (7); /* shift count & 1 */ - - output_asm_insn (AS2 (shr%B0,%1,%0), xops); - - output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops); - output_asm_insn (AS2 (shr%L3,%0,%3), xops); - - RET; -}") - -(define_insn "lshrsi3" - [(set (match_operand:SI 0 "general_operand" "=rm") - (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (shr%L0,%b2,%0); - else - return AS2 (shr%L0,%2,%1); -}") - -(define_insn "lshrhi3" - [(set (match_operand:HI 0 "general_operand" "=rm") - (lshiftrt:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (shr%W0,%b2,%0); - else - return AS2 (shr%W0,%2,%0); -}") - -(define_insn "lshrqi3" - [(set (match_operand:QI 0 "general_operand" "=qm") - (lshiftrt:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (shr%B0,%b2,%0); - else - return AS2 (shr%B0,%2,%0); -}") - -;;- rotate instructions - -(define_insn "rotlsi3" - [(set (match_operand:SI 0 "general_operand" "=rm") - (rotate:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (rol%L0,%b2,%0); - else - return AS2 (rol%L0,%2,%0); -}") - -(define_insn "rotlhi3" - [(set (match_operand:HI 0 "general_operand" "=rm") - (rotate:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (rol%W0,%b2,%0); - else - return AS2 (rol%W0,%2,%0); -}") - -(define_insn "rotlqi3" - [(set (match_operand:QI 0 "general_operand" "=qm") - (rotate:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (rol%B0,%b2,%0); - else - return AS2 (rol%B0,%2,%0); -}") - -(define_insn "rotrsi3" - [(set (match_operand:SI 0 "general_operand" "=rm") - (rotatert:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (ror%L0,%b2,%0); - else - return AS2 (ror%L0,%2,%0); -}") - -(define_insn "rotrhi3" - [(set (match_operand:HI 0 "general_operand" "=rm") - (rotatert:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (ror%W0,%b2,%0); - else - return AS2 (ror%W0,%2,%0); -}") - -(define_insn "rotrqi3" - [(set (match_operand:QI 0 "general_operand" "=qm") - (rotatert:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "cI")))] - "" - "* -{ - if (REG_P (operands[2])) - return AS2 (ror%B0,%b2,%0); - else - return AS2 (ror%B0,%2,%0); -}") - -/* -;; This usually looses. But try a define_expand to recognize a few case -;; we can do efficiently, such as accessing the "high" QImode registers, -;; %ah, %bh, %ch, %dh. -(define_insn "insv" - [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r") - (match_operand:SI 1 "general_operand" "i") - (match_operand:SI 2 "general_operand" "i")) - (match_operand:SI 3 "general_operand" "ri"))] - "" - "* -{ - if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode)) - abort (); - if (GET_CODE (operands[3]) == CONST_INT) - { - unsigned int mask = (1 << INTVAL (operands[1])) - 1; - operands[1] = GEN_INT (~(mask << INTVAL (operands[2]))); - output_asm_insn (AS2 (and%L0,%1,%0), operands); - operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2])); - output_asm_insn (AS2 (or%L0,%3,%0), operands); - } - else - { - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0])); - if (INTVAL (operands[2])) - output_asm_insn (AS2 (ror%L0,%2,%0), operands); - output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands); - operands[2] = GEN_INT (BITS_PER_WORD - - INTVAL (operands[1]) - INTVAL (operands[2])); - if (INTVAL (operands[2])) - output_asm_insn (AS2 (ror%L0,%2,%0), operands); - } - RET; -}") -*/ -/* -;; ??? There are problems with the mode of operand[3]. The point of this -;; is to represent an HImode move to a "high byte" register. - -(define_expand "insv" - [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "immediate_operand" "") - (match_operand:SI 2 "immediate_operand" "")) - (match_operand:QI 3 "general_operand" "ri"))] - "" - " -{ - if (GET_CODE (operands[1]) != CONST_INT - || GET_CODE (operands[2]) != CONST_INT) - FAIL; - - if (! (INTVAL (operands[1]) == 8 - && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0)) - && ! INTVAL (operands[1]) == 1) - FAIL; -}") - -;; ??? Are these constraints right? -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+&qo") - (const_int 8) - (const_int 8)) - (match_operand:QI 1 "general_operand" "qn"))] - "" - "* -{ - if (REG_P (operands[0])) - return AS2 (mov%B0,%1,%h0); - - operands[0] = adj_offsettable_operand (operands[0], 1); - return AS2 (mov%B0,%1,%0); -}") -*/ - -;; On i386, the register count for a bit operation is *not* truncated, -;; so SHIFT_COUNT_TRUNCATED must not be defined. - -;; On i486, the shift & or/and code is faster than bts or btr. If -;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code. - -;; On i386, bts is a little faster if operands[0] is a reg, and a -;; little slower if operands[0] is a MEM, than the shift & or/and code. -;; Use bts & btr, since they reload better. - -;; General bit set and clear. -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+rm") - (const_int 1) - (match_operand:SI 2 "general_operand" "r")) - (match_operand:SI 3 "const_int_operand" "n"))] - "TARGET_386 && GET_CODE (operands[2]) != CONST_INT" - "* -{ - CC_STATUS_INIT; - - if (INTVAL (operands[3]) == 1) - return AS2 (bts%L0,%2,%0); - else - return AS2 (btr%L0,%2,%0); -}") - -;; Bit complement. See comments on previous pattern. -;; ??? Is this really worthwhile? -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=rm") - (xor:SI (ashift:SI (const_int 1) - (match_operand:SI 1 "general_operand" "r")) - (match_operand:SI 2 "general_operand" "0")))] - "TARGET_386 && GET_CODE (operands[1]) != CONST_INT" - "* -{ - CC_STATUS_INIT; - - return AS2 (btc%L0,%1,%0); -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=rm") - (xor:SI (match_operand:SI 1 "general_operand" "0") - (ashift:SI (const_int 1) - (match_operand:SI 2 "general_operand" "r"))))] - "TARGET_386 && GET_CODE (operands[2]) != CONST_INT" - "* -{ - CC_STATUS_INIT; - - return AS2 (btc%L0,%2,%0); -}") - -;; Recognizers for bit-test instructions. - -;; The bt opcode allows a MEM in operands[0]. But on both i386 and -;; i486, it is faster to copy a MEM to REG and then use bt, than to use -;; bt on the MEM directly. - -;; ??? The first argument of a zero_extract must not be reloaded, so -;; don't allow a MEM in the operand predicate without allowing it in the -;; constraint. - -(define_insn "" - [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r") - (const_int 1) - (match_operand:SI 1 "general_operand" "r")))] - "GET_CODE (operands[1]) != CONST_INT" - "* -{ - cc_status.flags |= CC_Z_IN_NOT_C; - return AS2 (bt%L0,%1,%0); -}") - -(define_insn "" - [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r") - (match_operand:SI 1 "const_int_operand" "n") - (match_operand:SI 2 "const_int_operand" "n")))] - "" - "* -{ - unsigned int mask; - - mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]); - operands[1] = GEN_INT (mask); - - if (QI_REG_P (operands[0])) - { - if ((mask & ~0xff) == 0) - { - cc_status.flags |= CC_NOT_NEGATIVE; - return AS2 (test%B0,%1,%b0); - } - - if ((mask & ~0xff00) == 0) - { - cc_status.flags |= CC_NOT_NEGATIVE; - operands[1] = GEN_INT (mask >> 8); - return AS2 (test%B0,%1,%h0); - } - } - - return AS2 (test%L0,%1,%0); -}") - -;; ??? All bets are off if operand 0 is a volatile MEM reference. -;; The CPU may access unspecified bytes around the actual target byte. - -(define_insn "" - [(set (cc0) (zero_extract (match_operand:QI 0 "general_operand" "rm") - (match_operand:SI 1 "const_int_operand" "n") - (match_operand:SI 2 "const_int_operand" "n")))] - "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])" - "* -{ - unsigned int mask; - - mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]); - operands[1] = GEN_INT (mask); - - if (! REG_P (operands[0]) || QI_REG_P (operands[0])) - { - if ((mask & ~0xff) == 0) - { - cc_status.flags |= CC_NOT_NEGATIVE; - return AS2 (test%B0,%1,%b0); - } - - if ((mask & ~0xff00) == 0) - { - cc_status.flags |= CC_NOT_NEGATIVE; - operands[1] = GEN_INT (mask >> 8); - - if (QI_REG_P (operands[0])) - return AS2 (test%B0,%1,%h0); - else - { - operands[0] = adj_offsettable_operand (operands[0], 1); - return AS2 (test%B0,%1,%b0); - } - } - - if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0) - { - cc_status.flags |= CC_NOT_NEGATIVE; - operands[1] = GEN_INT (mask >> 16); - operands[0] = adj_offsettable_operand (operands[0], 2); - return AS2 (test%B0,%1,%b0); - } - - if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0) - { - cc_status.flags |= CC_NOT_NEGATIVE; - operands[1] = GEN_INT (mask >> 24); - operands[0] = adj_offsettable_operand (operands[0], 3); - return AS2 (test%B0,%1,%b0); - } - } - - if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM) - return AS2 (test%L0,%1,%0); - - return AS2 (test%L1,%0,%1); -}") - -;; Store-flag instructions. - -;; For all sCOND expanders, also expand the compare or test insn that -;; generates cc0. Generate an equality comparison if `seq' or `sne'. - -;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may -;; not have any input reloads. A MEM write might need an input reload -;; for the address of the MEM. So don't allow MEM as the SET_DEST. - -(define_expand "seq" - [(match_dup 1) - (set (match_operand:QI 0 "register_operand" "") - (eq:QI (cc0) (const_int 0)))] - "" - " -{ - if (TARGET_IEEE_FP - && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT) - operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1); - else - operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); -}") - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (eq:QI (cc0) (const_int 0)))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return AS1 (setnb,%0); - else - return AS1 (sete,%0); -}") - -(define_expand "sne" - [(match_dup 1) - (set (match_operand:QI 0 "register_operand" "") - (ne:QI (cc0) (const_int 0)))] - "" - " -{ - if (TARGET_IEEE_FP - && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT) - operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1); - else - operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); -}") - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (ne:QI (cc0) (const_int 0)))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return AS1 (setb,%0); - else - return AS1 (setne,%0); -} -") - -(define_expand "sgt" - [(match_dup 1) - (set (match_operand:QI 0 "register_operand" "") - (gt:QI (cc0) (const_int 0)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (gt:QI (cc0) (const_int 0)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) - return AS1 (sete,%0); - - OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR); -}") - -(define_expand "sgtu" - [(match_dup 1) - (set (match_operand:QI 0 "register_operand" "") - (gtu:QI (cc0) (const_int 0)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (gtu:QI (cc0) (const_int 0)))] - "" - "* return \"seta %0\"; ") - -(define_expand "slt" - [(match_dup 1) - (set (match_operand:QI 0 "register_operand" "") - (lt:QI (cc0) (const_int 0)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (lt:QI (cc0) (const_int 0)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) - return AS1 (sete,%0); - - OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\"); -}") - -(define_expand "sltu" - [(match_dup 1) - (set (match_operand:QI 0 "register_operand" "") - (ltu:QI (cc0) (const_int 0)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (ltu:QI (cc0) (const_int 0)))] - "" - "* return \"setb %0\"; ") - -(define_expand "sge" - [(match_dup 1) - (set (match_operand:QI 0 "register_operand" "") - (ge:QI (cc0) (const_int 0)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (ge:QI (cc0) (const_int 0)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) - return AS1 (sete,%0); - - OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\"); -}") - -(define_expand "sgeu" - [(match_dup 1) - (set (match_operand:QI 0 "register_operand" "") - (geu:QI (cc0) (const_int 0)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (geu:QI (cc0) (const_int 0)))] - "" - "* return \"setae %0\"; ") - -(define_expand "sle" - [(match_dup 1) - (set (match_operand:QI 0 "register_operand" "") - (le:QI (cc0) (const_int 0)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (le:QI (cc0) (const_int 0)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) - return AS1 (setb,%0); - - OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR); -}") - -(define_expand "sleu" - [(match_dup 1) - (set (match_operand:QI 0 "register_operand" "") - (leu:QI (cc0) (const_int 0)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (leu:QI (cc0) (const_int 0)))] - "" - "* return \"setbe %0\"; ") - -;; Basic conditional jump instructions. -;; We ignore the overflow flag for signed branch instructions. - -;; For all bCOND expanders, also expand the compare or test insn that -;; generates cc0. Generate an equality comparison if `beq' or `bne'. - -(define_expand "beq" - [(match_dup 1) - (set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - if (TARGET_IEEE_FP - && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT) - operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1); - else - operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); -}") - -(define_insn "" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return \"jnc %l0\"; - else - return \"je %l0\"; -}") - -(define_expand "bne" - [(match_dup 1) - (set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - if (TARGET_IEEE_FP - && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT) - operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1); - else - operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); -}") - -(define_insn "" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return \"jc %l0\"; - else - return \"jne %l0\"; -}") - -(define_expand "bgt" - [(match_dup 1) - (set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) - return AS1 (je,%l0); - - OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR); -}") - -(define_expand "bgtu" - [(match_dup 1) - (set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "ja %l0") - -(define_expand "blt" - [(match_dup 1) - (set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) - return AS1 (je,%l0); - - OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\"); -}") - -(define_expand "bltu" - [(match_dup 1) - (set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jb %l0") - -(define_expand "bge" - [(match_dup 1) - (set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) - return AS1 (je,%l0); - - OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\"); -}") - -(define_expand "bgeu" - [(match_dup 1) - (set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jae %l0") - -(define_expand "ble" - [(match_dup 1) - (set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) - return AS1 (jb,%l0); - - OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR); -}") - -(define_expand "bleu" - [(match_dup 1) - (set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jbe %l0") - -;; Negated conditional jump instructions. - -(define_insn "" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return \"jc %l0\"; - else - return \"jne %l0\"; -}") - -(define_insn "" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return \"jnc %l0\"; - else - return \"je %l0\"; -}") - -(define_insn "" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) - return AS1 (jne,%l0); - - OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR); -}") - -(define_insn "" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "jbe %l0") - -(define_insn "" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) - return AS1 (jne,%l0); - - OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\"); -}") - -(define_insn "" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "jae %l0") - -(define_insn "" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) - return AS1 (jne,%l0); - - OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\"); -}") - -(define_insn "" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "jb %l0") - -(define_insn "" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) - return AS1 (jae,%l0); - - OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR); -}") - -(define_insn "" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "ja %l0") - -;; Unconditional and other jump instructions - -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "jmp %l0") - -(define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "general_operand" "rm"))] - "" - "* -{ - CC_STATUS_INIT; - - return AS1 (jmp,%*%0); -}") - -;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i); -;; if S does not change i - -(define_expand "decrement_and_branch_until_zero" - [(parallel [(set (pc) - (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "") - (const_int -1)) - (const_int 0)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (const_int -1)))])] - "" - "") - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "arithmetic_comparison_operator" - [(plus:SI (match_operand:SI 1 "general_operand" "+r,m") - (match_operand:SI 2 "general_operand" "rmi,ri")) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc))) - (set (match_dup 1) - (plus:SI (match_dup 1) - (match_dup 2)))] - "" - "* -{ - CC_STATUS_INIT; - if (operands[2] == constm1_rtx) - output_asm_insn (AS1 (dec%L1,%1), operands); - - else if (operands[1] == const1_rtx) - output_asm_insn (AS1 (inc%L1,%1), operands); - - else - output_asm_insn (AS2 (add%L1,%2,%1), operands); - - return AS1 (%J0,%l3); -}") - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "arithmetic_comparison_operator" - [(minus:SI (match_operand:SI 1 "general_operand" "+r,m") - (match_operand:SI 2 "general_operand" "rmi,ri")) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc))) - (set (match_dup 1) - (minus:SI (match_dup 1) - (match_dup 2)))] - "" - "* -{ - CC_STATUS_INIT; - if (operands[2] == const1_rtx) - output_asm_insn (AS1 (dec%L1,%1), operands); - - else if (operands[1] == constm1_rtx) - output_asm_insn (AS1 (inc%L1,%1), operands); - - else - output_asm_insn (AS2 (sub%L1,%2,%1), operands); - - return AS1 (%J0,%l3); -}") - -;; Implement switch statements when generating PIC code. Switches are -;; implemented by `tablejump' when not using -fpic. - -;; Emit code here to do the range checking and make the index zero based. - -(define_expand "casesi" - [(set (match_dup 5) - (minus:SI (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "general_operand" ""))) - (set (cc0) - (compare:CC (match_dup 5) - (match_operand:SI 2 "general_operand" ""))) - (set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 4 "" "")) - (pc))) - (parallel - [(set (pc) - (minus:SI (reg:SI 3) - (mem:SI (plus:SI (mult:SI (match_dup 5) - (const_int 4)) - (label_ref (match_operand 3 "" "")))))) - (clobber (match_scratch:SI 6 ""))])] - "flag_pic" - " -{ - operands[5] = gen_reg_rtx (SImode); - current_function_uses_pic_offset_table = 1; -}") - -;; Implement a casesi insn. - -;; Each entry in the "addr_diff_vec" looks like this as the result of the -;; two rules below: -;; -;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2] -;; -;; 1. An expression involving an external reference may only use the -;; addition operator, and only with an assembly-time constant. -;; The example above satisfies this because ".-.L2" is a constant. -;; -;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is -;; given the value of "GOT - .", where GOT is the actual address of -;; the Global Offset Table. Therefore, the .long above actually -;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The -;; expression "GOT - .L2" by itself would generate an error from as(1). -;; -;; The pattern below emits code that looks like this: -;; -;; movl %ebx,reg -;; subl TABLE@GOTOFF(%ebx,index,4),reg -;; jmp reg -;; -;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since -;; the addr_diff_vec is known to be part of this module. -;; -;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which -;; evaluates to just ".L2". - -(define_insn "" - [(set (pc) - (minus:SI (reg:SI 3) - (mem:SI (plus:SI - (mult:SI (match_operand:SI 0 "register_operand" "r") - (const_int 4)) - (label_ref (match_operand 1 "" "")))))) - (clobber (match_scratch:SI 2 "=&r"))] - "" - "* -{ - rtx xops[4]; - - xops[0] = operands[0]; - xops[1] = operands[1]; - xops[2] = operands[2]; - xops[3] = pic_offset_table_rtx; - - output_asm_insn (AS2 (mov%L2,%3,%2), xops); - output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops); - output_asm_insn (AS1 (jmp,%*%2), xops); - ASM_OUTPUT_ALIGN_CODE (asm_out_file); - RET; -}") - -(define_insn "tablejump" - [(set (pc) (match_operand:SI 0 "general_operand" "rm")) - (use (label_ref (match_operand 1 "" "")))] - "" - "* -{ - CC_STATUS_INIT; - - return AS1 (jmp,%*%0); -}") - -;; Call insns. - -;; If generating PIC code, the predicate indirect_operand will fail -;; for operands[0] containing symbolic references on all of the named -;; call* patterns. Each named pattern is followed by an unnamed pattern -;; that matches any call to a symbolic CONST (ie, a symbol_ref). The -;; unnamed patterns are only used while generating PIC code, because -;; otherwise the named patterns match. - -;; Call subroutine returning no value. - -(define_expand "call_pop" - [(parallel [(call (match_operand:QI 0 "indirect_operand" "") - (match_operand:SI 1 "general_operand" "")) - (set (reg:SI 7) - (plus:SI (reg:SI 7) - (match_operand:SI 3 "immediate_operand" "")))])] - "" - " -{ - rtx addr; - - if (flag_pic) - current_function_uses_pic_offset_table = 1; - - /* With half-pic, force the address into a register. */ - addr = XEXP (operands[0], 0); - if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) - XEXP (operands[0], 0) = force_reg (Pmode, addr); - - if (! expander_call_insn_operand (operands[0], QImode)) - operands[0] - = change_address (operands[0], VOIDmode, - copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); -}") - -(define_insn "" - [(call (match_operand:QI 0 "call_insn_operand" "m") - (match_operand:SI 1 "general_operand" "g")) - (set (reg:SI 7) (plus:SI (reg:SI 7) - (match_operand:SI 3 "immediate_operand" "i")))] - "" - "* -{ - if (GET_CODE (operands[0]) == MEM - && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) - { - operands[0] = XEXP (operands[0], 0); - return AS1 (call,%*%0); - } - else - return AS1 (call,%P0); -}") - -(define_insn "" - [(call (mem:QI (match_operand:SI 0 "symbolic_operand" "")) - (match_operand:SI 1 "general_operand" "g")) - (set (reg:SI 7) (plus:SI (reg:SI 7) - (match_operand:SI 3 "immediate_operand" "i")))] - "!HALF_PIC_P ()" - "call %P0") - -(define_expand "call" - [(call (match_operand:QI 0 "indirect_operand" "") - (match_operand:SI 1 "general_operand" ""))] - ;; Operand 1 not used on the i386. - "" - " -{ - rtx addr; - - if (flag_pic) - current_function_uses_pic_offset_table = 1; - - /* With half-pic, force the address into a register. */ - addr = XEXP (operands[0], 0); - if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) - XEXP (operands[0], 0) = force_reg (Pmode, addr); - - if (! expander_call_insn_operand (operands[0], QImode)) - operands[0] - = change_address (operands[0], VOIDmode, - copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); -}") - -(define_insn "" - [(call (match_operand:QI 0 "call_insn_operand" "m") - (match_operand:SI 1 "general_operand" "g"))] - ;; Operand 1 not used on the i386. - "" - "* -{ - if (GET_CODE (operands[0]) == MEM - && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) - { - operands[0] = XEXP (operands[0], 0); - return AS1 (call,%*%0); - } - else - return AS1 (call,%P0); -}") - -(define_insn "" - [(call (mem:QI (match_operand:SI 0 "symbolic_operand" "")) - (match_operand:SI 1 "general_operand" "g"))] - ;; Operand 1 not used on the i386. - "!HALF_PIC_P ()" - "call %P0") - -;; Call subroutine, returning value in operand 0 -;; (which must be a hard register). - -(define_expand "call_value_pop" - [(parallel [(set (match_operand 0 "" "") - (call (match_operand:QI 1 "indirect_operand" "") - (match_operand:SI 2 "general_operand" ""))) - (set (reg:SI 7) - (plus:SI (reg:SI 7) - (match_operand:SI 4 "immediate_operand" "")))])] - "" - " -{ - rtx addr; - - if (flag_pic) - current_function_uses_pic_offset_table = 1; - - /* With half-pic, force the address into a register. */ - addr = XEXP (operands[1], 0); - if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) - XEXP (operands[1], 0) = force_reg (Pmode, addr); - - if (! expander_call_insn_operand (operands[1], QImode)) - operands[1] - = change_address (operands[1], VOIDmode, - copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); -}") - -(define_insn "" - [(set (match_operand 0 "" "=rf") - (call (match_operand:QI 1 "call_insn_operand" "m") - (match_operand:SI 2 "general_operand" "g"))) - (set (reg:SI 7) (plus:SI (reg:SI 7) - (match_operand:SI 4 "immediate_operand" "i")))] - "" - "* -{ - if (GET_CODE (operands[1]) == MEM - && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) - { - operands[1] = XEXP (operands[1], 0); - output_asm_insn (AS1 (call,%*%1), operands); - } - else - output_asm_insn (AS1 (call,%P1), operands); - - RET; -}") - -(define_insn "" - [(set (match_operand 0 "" "=rf") - (call (mem:QI (match_operand:SI 1 "symbolic_operand" "")) - (match_operand:SI 2 "general_operand" "g"))) - (set (reg:SI 7) (plus:SI (reg:SI 7) - (match_operand:SI 4 "immediate_operand" "i")))] - "!HALF_PIC_P ()" - "call %P1") - -(define_expand "call_value" - [(set (match_operand 0 "" "") - (call (match_operand:QI 1 "indirect_operand" "") - (match_operand:SI 2 "general_operand" "")))] - ;; Operand 2 not used on the i386. - "" - " -{ - rtx addr; - - if (flag_pic) - current_function_uses_pic_offset_table = 1; - - /* With half-pic, force the address into a register. */ - addr = XEXP (operands[1], 0); - if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) - XEXP (operands[1], 0) = force_reg (Pmode, addr); - - if (! expander_call_insn_operand (operands[1], QImode)) - operands[1] - = change_address (operands[1], VOIDmode, - copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); -}") - -(define_insn "" - [(set (match_operand 0 "" "=rf") - (call (match_operand:QI 1 "call_insn_operand" "m") - (match_operand:SI 2 "general_operand" "g")))] - ;; Operand 2 not used on the i386. - "" - "* -{ - if (GET_CODE (operands[1]) == MEM - && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) - { - operands[1] = XEXP (operands[1], 0); - output_asm_insn (AS1 (call,%*%1), operands); - } - else - output_asm_insn (AS1 (call,%P1), operands); - - RET; -}") - -(define_insn "" - [(set (match_operand 0 "" "=rf") - (call (mem:QI (match_operand:SI 1 "symbolic_operand" "")) - (match_operand:SI 2 "general_operand" "g")))] - ;; Operand 2 not used on the i386. - "!HALF_PIC_P ()" - "call %P1") - -;; Call subroutine returning any type. - -(define_expand "untyped_call" - [(parallel [(call (match_operand 0 "" "") - (const_int 0)) - (match_operand 1 "" "") - (match_operand 2 "" "")])] - "" - " -{ - int i; - - /* In order to give reg-stack an easier job in validating two - coprocessor registers as containing a possible return value, - simply pretend the untyped call returns a complex long double - value. */ - emit_call_insn (TARGET_80387 - ? gen_call_value (gen_rtx (REG, XCmode, FIRST_FLOAT_REG), - operands[0], const0_rtx) - : gen_call (operands[0], const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - /* The optimizer does not know that the call sets the function value - registers we stored in the result block. We avoid problems by - claiming that all hard registers are used and clobbered at this - point. */ - emit_insn (gen_blockage ()); - - DONE; -}") - -;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and -;; all of memory. This blocks insns from being moved across this point. - -(define_insn "blockage" - [(unspec_volatile [(const_int 0)] 0)] - "" - "") - -;; Insn emitted into the body of a function to return from a function. -;; This is only done if the function's epilogue is known to be simple. -;; See comments for simple_386_epilogue in i386.c. - -(define_insn "return" - [(return)] - "simple_386_epilogue ()" - "* -{ - function_epilogue (asm_out_file, get_frame_size ()); - RET; -}") - -(define_insn "nop" - [(const_int 0)] - "" - "nop") - -(define_expand "movstrsi" - [(parallel [(set (match_operand:BLK 0 "memory_operand" "") - (match_operand:BLK 1 "memory_operand" "")) - (use (match_operand:SI 2 "const_int_operand" "")) - (use (match_operand:SI 3 "const_int_operand" "")) - (clobber (match_scratch:SI 4 "")) - (clobber (match_dup 5)) - (clobber (match_dup 6))])] - "" - " -{ - rtx addr0, addr1; - - if (GET_CODE (operands[2]) != CONST_INT) - FAIL; - - addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); - addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); - - operands[5] = addr0; - operands[6] = addr1; - - operands[0] = gen_rtx (MEM, BLKmode, addr0); - operands[1] = gen_rtx (MEM, BLKmode, addr1); -}") - -;; It might seem that operands 0 & 1 could use predicate register_operand. -;; But strength reduction might offset the MEM expression. So we let -;; reload put the address into %edi & %esi. - -(define_insn "" - [(set (mem:BLK (match_operand:SI 0 "address_operand" "D")) - (mem:BLK (match_operand:SI 1 "address_operand" "S"))) - (use (match_operand:SI 2 "const_int_operand" "n")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_scratch:SI 4 "=&c")) - (clobber (match_dup 0)) - (clobber (match_dup 1))] - "" - "* -{ - rtx xops[2]; - - output_asm_insn (\"cld\", operands); - if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) & ~0x03) - { - xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff); - xops[1] = operands[4]; - - output_asm_insn (AS2 (mov%L1,%0,%1), xops); -#ifdef INTEL_SYNTAX - output_asm_insn (\"rep movsd\", xops); -#else - output_asm_insn (\"rep\;movsl\", xops); -#endif - } - if (INTVAL (operands[2]) & 0x02) - output_asm_insn (\"movsw\", operands); - if (INTVAL (operands[2]) & 0x01) - output_asm_insn (\"movsb\", operands); - } - else - abort (); - RET; -}") - -(define_expand "cmpstrsi" - [(parallel [(set (match_operand:SI 0 "general_operand" "") - (compare:SI (match_operand:BLK 1 "general_operand" "") - (match_operand:BLK 2 "general_operand" ""))) - (use (match_operand:SI 3 "general_operand" "")) - (use (match_operand:SI 4 "immediate_operand" "")) - (clobber (match_dup 5)) - (clobber (match_dup 6)) - (clobber (match_dup 3))])] - "" - " -{ - rtx addr1, addr2; - - addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); - addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); - operands[3] = copy_to_mode_reg (SImode, operands[3]); - - operands[5] = addr1; - operands[6] = addr2; - - operands[1] = gen_rtx (MEM, BLKmode, addr1); - operands[2] = gen_rtx (MEM, BLKmode, addr2); - -}") - -;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is -;; zero. Emit extra code to make sure that a zero-length compare is EQ. - -;; It might seem that operands 0 & 1 could use predicate register_operand. -;; But strength reduction might offset the MEM expression. So we let -;; reload put the address into %edi & %esi. - -;; ??? Most comparisons have a constant length, and it's therefore -;; possible to know that the length is non-zero, and to avoid the extra -;; code to handle zero-length compares. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=&r") - (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S")) - (mem:BLK (match_operand:SI 2 "address_operand" "D")))) - (use (match_operand:SI 3 "register_operand" "c")) - (use (match_operand:SI 4 "immediate_operand" "i")) - (clobber (match_dup 1)) - (clobber (match_dup 2)) - (clobber (match_dup 3))] - "" - "* -{ - rtx xops[4], label; - - label = gen_label_rtx (); - - output_asm_insn (\"cld\", operands); - output_asm_insn (AS2 (xor%L0,%0,%0), operands); - output_asm_insn (\"repz\;cmps%B2\", operands); - output_asm_insn (\"je %l0\", &label); - - xops[0] = operands[0]; - xops[1] = gen_rtx (MEM, QImode, - gen_rtx (PLUS, SImode, operands[1], constm1_rtx)); - xops[2] = gen_rtx (MEM, QImode, - gen_rtx (PLUS, SImode, operands[2], constm1_rtx)); - xops[3] = operands[3]; - - output_asm_insn (AS2 (movz%B1%L0,%1,%0), xops); - output_asm_insn (AS2 (movz%B2%L3,%2,%3), xops); - - output_asm_insn (AS2 (sub%L0,%3,%0), xops); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label)); - RET; -}") - -(define_insn "" - [(set (cc0) - (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S")) - (mem:BLK (match_operand:SI 1 "address_operand" "D")))) - (use (match_operand:SI 2 "register_operand" "c")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_dup 0)) - (clobber (match_dup 1)) - (clobber (match_dup 2))] - "" - "* -{ - rtx xops[2]; - - cc_status.flags |= CC_NOT_SIGNED; - - xops[0] = gen_rtx (REG, QImode, 0); - xops[1] = CONST0_RTX (QImode); - - output_asm_insn (\"cld\", operands); - output_asm_insn (AS2 (test%B0,%1,%0), xops); - return \"repz\;cmps%B2\"; -}") - -(define_expand "ffssi2" - [(set (match_dup 2) - (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" "")) - (const_int -1))) - (set (match_operand:SI 0 "general_operand" "") - (plus:SI (match_dup 2) (const_int 1)))] - "" - "operands[2] = gen_reg_rtx (SImode);") - -;; Note, you cannot optimize away the branch following the bsfl by assuming -;; that the destination is not modified if the input is 0, since not all -;; x86 implementations do this. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=&r") - (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" "rm")) - (const_int -1)))] - "" - "* -{ - rtx xops[3]; - static int ffssi_label_number; - char buffer[30]; - - xops[0] = operands[0]; - xops[1] = operands[1]; - xops[2] = constm1_rtx; - output_asm_insn (AS2 (bsf%L0,%1,%0), xops); -#ifdef LOCAL_LABEL_PREFIX - sprintf (buffer, \"jnz %sLFFSSI%d\", - LOCAL_LABEL_PREFIX, ffssi_label_number); -#else - sprintf (buffer, \"jnz %sLFFSSI%d\", - \"\", ffssi_label_number); -#endif - output_asm_insn (buffer, xops); - output_asm_insn (AS2 (mov%L0,%2,%0), xops); -#ifdef LOCAL_LABEL_PREFIX - sprintf (buffer, \"%sLFFSSI%d:\", - LOCAL_LABEL_PREFIX, ffssi_label_number); -#else - sprintf (buffer, \"%sLFFSSI%d:\", - \"\", ffssi_label_number); -#endif - output_asm_insn (buffer, xops); - - ffssi_label_number++; - return \"\"; -}") - -(define_expand "ffshi2" - [(set (match_dup 2) - (plus:HI (ffs:HI (match_operand:HI 1 "general_operand" "")) - (const_int -1))) - (set (match_operand:HI 0 "general_operand" "") - (plus:HI (match_dup 2) (const_int 1)))] - "" - "operands[2] = gen_reg_rtx (HImode);") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=&r") - (plus:HI (ffs:HI (match_operand:SI 1 "general_operand" "rm")) - (const_int -1)))] - "" - "* -{ - rtx xops[3]; - static int ffshi_label_number; - char buffer[30]; - - xops[0] = operands[0]; - xops[1] = operands[1]; - xops[2] = constm1_rtx; - output_asm_insn (AS2 (bsf%W0,%1,%0), xops); -#ifdef LOCAL_LABEL_PREFIX - sprintf (buffer, \"jnz %sLFFSHI%d\", - LOCAL_LABEL_PREFIX, ffshi_label_number); -#else - sprintf (buffer, \"jnz %sLFFSHI%d\", - \"\", ffshi_label_number); -#endif - output_asm_insn (buffer, xops); - output_asm_insn (AS2 (mov%W0,%2,%0), xops); -#ifdef LOCAL_LABEL_PREFIX - sprintf (buffer, \"%sLFFSHI%d:\", - LOCAL_LABEL_PREFIX, ffshi_label_number); -#else - sprintf (buffer, \"%sLFFSHI%d:\", - \"\", ffshi_label_number); -#endif - output_asm_insn (buffer, xops); - - ffshi_label_number++; - return \"\"; -}") - -;; These patterns match the binary 387 instructions for addM3, subM3, -;; mulM3 and divM3. There are three patterns for each of DFmode and -;; SFmode. The first is the normal insn, the second the same insn but -;; with one operand a conversion, and the third the same insn but with -;; the other operand a conversion. The conversion may be SFmode or -;; SImode if the target mode DFmode, but only SImode if the target mode -;; is SFmode. - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (match_operator:DF 3 "binary_387_op" - [(match_operand:DF 1 "nonimmediate_operand" "0,fm") - (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);") - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 3 "binary_387_op" - [(float:DF (match_operand:SI 1 "general_operand" "rm")) - (match_operand:DF 2 "general_operand" "0")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);") - -(define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f,f") - (match_operator:XF 3 "binary_387_op" - [(match_operand:XF 1 "nonimmediate_operand" "0,f") - (match_operand:XF 2 "nonimmediate_operand" "f,0")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);") - -(define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f") - (match_operator:XF 3 "binary_387_op" - [(float:XF (match_operand:SI 1 "general_operand" "rm")) - (match_operand:XF 2 "general_operand" "0")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);") - -(define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f,f") - (match_operator:XF 3 "binary_387_op" - [(float_extend:XF (match_operand:SF 1 "general_operand" "fm,0")) - (match_operand:XF 2 "general_operand" "0,f")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);") - -(define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f") - (match_operator:XF 3 "binary_387_op" - [(match_operand:XF 1 "general_operand" "0") - (float:XF (match_operand:SI 2 "general_operand" "rm"))]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);") - -(define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f,f") - (match_operator:XF 3 "binary_387_op" - [(match_operand:XF 1 "general_operand" "0,f") - (float_extend:XF - (match_operand:SF 2 "general_operand" "fm,0"))]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);") - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (match_operator:DF 3 "binary_387_op" - [(float_extend:DF (match_operand:SF 1 "general_operand" "fm,0")) - (match_operand:DF 2 "general_operand" "0,f")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);") - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 3 "binary_387_op" - [(match_operand:DF 1 "general_operand" "0") - (float:DF (match_operand:SI 2 "general_operand" "rm"))]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);") - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (match_operator:DF 3 "binary_387_op" - [(match_operand:DF 1 "general_operand" "0,f") - (float_extend:DF - (match_operand:SF 2 "general_operand" "fm,0"))]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);") - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (match_operator:SF 3 "binary_387_op" - [(match_operand:SF 1 "nonimmediate_operand" "0,fm") - (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);") - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (match_operator:SF 3 "binary_387_op" - [(float:SF (match_operand:SI 1 "general_operand" "rm")) - (match_operand:SF 2 "general_operand" "0")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);") - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (match_operator:SF 3 "binary_387_op" - [(match_operand:SF 1 "general_operand" "0") - (float:SF (match_operand:SI 2 "general_operand" "rm"))]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);") - -(define_expand "strlensi" - [(parallel [(set (match_dup 4) - (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" "")) - (match_operand:QI 2 "register_operand" "") - (match_operand:SI 3 "immediate_operand" "")] 0)) - (clobber (match_dup 1))]) - (set (match_dup 5) - (not:SI (match_dup 4))) - (set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_dup 5) - (const_int 1)))] - "" - " -{ - operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); - operands[4] = gen_reg_rtx (SImode); - operands[5] = gen_reg_rtx (SImode); -}") - -;; It might seem that operands 0 & 1 could use predicate register_operand. -;; But strength reduction might offset the MEM expression. So we let -;; reload put the address into %edi. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=&c") - (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D")) - (match_operand:QI 2 "register_operand" "a") - (match_operand:SI 3 "immediate_operand" "i")] 0)) - (clobber (match_dup 1))] - "" - "* -{ - rtx xops[2]; - - xops[0] = operands[0]; - xops[1] = constm1_rtx; - output_asm_insn (\"cld\", operands); - output_asm_insn (AS2 (mov%L0,%1,%0), xops); - return \"repnz\;scas%B2\"; -}") diff --git a/support/cpp/i386/i386iscgas.h b/support/cpp/i386/i386iscgas.h deleted file mode 100644 index 526fe374..00000000 --- a/support/cpp/i386/i386iscgas.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Definitions for Intel 386 running Interactive Unix System V, - producing stabs-in-coff output (using a slightly modified gas). - Specifically, this is for recent versions that support POSIX; - for version 2.0.2, use configuration option i386-sysv instead. */ - -/* Underscores are not used on ISC systems (probably not on any COFF - system), despite the comments in i386/gas.h. If this is not defined, - enquire (for example) will fail to link. --karl@cs.umb.edu */ -#define NO_UNDERSCORES - -/* Mostly like other gas-using systems. */ -#include "i386/gas.h" - -/* But with ISC-specific additions. */ -#include "i386/isc.h" - -/* We do not want to output SDB debugging information. */ - -#undef SDB_DEBUGGING_INFO - -/* We want to output DBX debugging information. */ - -#define DBX_DEBUGGING_INFO - - -/* The function `dbxout_init' in dbxout.c omits the first character of - `ltext_label_name' when outputting the main source directory and main - source filename. I don't understand why, but rather than making a - system-independent change there, I override dbxout.c's defaults. - Perhaps it would be better to use ".Ltext0" instead of - `ltext_label_name', but we've already generated the label, so we just - use it here. --karl@cs.umb.edu */ -#define DBX_OUTPUT_MAIN_SOURCE_DIRECTORY(asmfile, cwd) \ - do { fprintf (asmfile, "%s ", ASM_STABS_OP); \ - output_quoted_string (asmfile, cwd); \ - fprintf (asmfile, ",%d,0,0,%s\n", N_SO, ltext_label_name); \ - } while (0) -#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(asmfile, input_file_name) \ - fprintf (asmfile, "%s ", ASM_STABS_OP); \ - output_quoted_string (input_file_name); \ - fprintf (asmfile, ",%d,0,0,%s\n", N_SO, ltext_label_name); \ - text_section (); \ - ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Ltext", 0) - - -/* Because we don't include `svr3.h', we haven't yet defined SIZE_TYPE - and PTRDIFF_TYPE. ISC's definitions don't match GCC's defaults, so: */ - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "int" - - -/* But we can't use crtbegin.o and crtend.o, because gas 1.38.1 doesn't - grok .section. The definitions here are otherwise identical to those - in i386/isc.h. */ -#undef STARTFILE_SPEC -#define STARTFILE_SPEC \ - "%{!shlib:%{posix:%{pg:mcrtp1.o%s}%{!pg:%{p:mcrtp1.o%s}%{!p:crtp1.o%s}}}\ - %{!posix:%{pg:mcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}\ - %{p:-L/lib/libp} %{pg:-L/lib/libp}}}\ - %{shlib:%{posix:crtp1.o%s}%{!posix:crt1.o%s}}" - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC "crtn.o%s" diff --git a/support/cpp/i386/isc.h b/support/cpp/i386/isc.h deleted file mode 100644 index cf8c5f69..00000000 --- a/support/cpp/i386/isc.h +++ /dev/null @@ -1,89 +0,0 @@ -/* Assembler-independent definitions for an Intel 386 running - Interactive Unix System V. Specifically, this is for recent versions - that support POSIX. */ - -/* Use crt1.o, not crt0.o, as a startup file, and crtn.o as a closing file. */ -#undef STARTFILE_SPEC -#define STARTFILE_SPEC \ - "%{!shlib:%{posix:%{pg:mcrtp1.o%s}%{!pg:%{p:mcrtp1.o%s}%{!p:crtp1.o%s}}}\ - %{Xp:%{pg:mcrtp1.o%s}%{!pg:%{p:mcrtp1.o%s}%{!p:crtp1.o%s}}}\ - %{!posix:%{!Xp:%{pg:mcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}\ - %{p:-L/lib/libp} %{pg:-L/lib/libp}}}}\ - %{shlib:%{Xp:crtp1.o%s}%{posix:crtp1.o%s}%{!posix:%{!Xp:crt1.o%s}}}\ - crtbegin.o%s" - -#define ENDFILE_SPEC "crtend.o%s crtn.o%s" - -/* Library spec */ -#undef LIB_SPEC -#define LIB_SPEC "%{shlib:-lc_s} %{posix:-lcposix} %{Xp:-lcposix} -lc -lg" - -#undef CPP_SPEC -#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{Xp:-D_POSIX_SOURCE}" - -/* ISC 2.2 uses `char' for `wchar_t'. */ -#undef WCHAR_TYPE -#define WCHAR_TYPE "char" - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE BITS_PER_UNIT - -#if 0 -/* This is apparently not true: ISC versions up to 3.0, at least, use - the standard calling sequence in which the called function pops the - extra arg. */ -/* caller has to pop the extra argument passed to functions that return - structures. */ - -#undef RETURN_POPS_ARGS -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \ - (TREE_CODE (FUNTYPE) == IDENTIFIER_NODE ? 0 \ - : (TARGET_RTD \ - && (TYPE_ARG_TYPES (FUNTYPE) == 0 \ - || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ - == void_type_node))) ? (SIZE) \ - : 0) -/* On other 386 systems, the last line looks like this: - : (aggregate_value_p (TREE_TYPE (FUNTYPE))) ? GET_MODE_SIZE (Pmode) : 0) */ -#endif - -/* Handle #pragma pack and #pragma weak. */ -#define HANDLE_SYSV_PRAGMA - -/* By default, target has a 80387, uses IEEE compatible arithmetic, - and returns float values in the 387, ie, - (TARGET_80387 | TARGET_FLOAT_RETURNS_IN_80387) - - ISC's software emulation of a 387 fails to handle the `fucomp' - opcode. fucomp is only used when generating IEEE compliant code. - So don't make TARGET_IEEE_FP default for ISC. */ - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT 0201 - -/* The ISC 2.0.2 software FPU emulator apparently can't handle - 80-bit XFmode insns, so don't generate them. */ -#undef LONG_DOUBLE_TYPE_SIZE -#define LONG_DOUBLE_TYPE_SIZE 64 - -/* The ISC assembler does not like a .file directive with a name - longer than 14 characters. Truncating it will not permit - debugging to work properly, but at least we won't get an error - message. */ - -#undef ASM_FILE_START -#define ASM_FILE_START(FILE) \ - do { \ - char c; \ - int max = 0; \ - char *string = dump_base_name; \ - \ - fputs ("\t.file\t\"", FILE); \ - \ - while ((c = *string++) != 0 && max++ < 14) { \ - if (c == '\"' || c == '\\') \ - putc ('\\', FILE); \ - putc (c, FILE); \ - } \ - fputs ("\"\n", FILE); \ - } while (0) diff --git a/support/cpp/i386/isccoff.h b/support/cpp/i386/isccoff.h deleted file mode 100644 index 383b9813..00000000 --- a/support/cpp/i386/isccoff.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Definitions for Intel 386 running Interactive Unix System V. - Specifically, this is for recent versions that support POSIX; - for version 2.0.2, use configuration option i386-sysv instead. - (But set TARGET_DEFAULT to 0201 if you do that, - if you don't have a real 80387.) */ - -/* Mostly it's like AT&T Unix System V. */ - -#include "i386/sysv3.h" - -/* But with a few changes. */ -#include "i386/isc.h" diff --git a/support/cpp/i386/iscdbx.h b/support/cpp/i386/iscdbx.h deleted file mode 100644 index 6c2d42e4..00000000 --- a/support/cpp/i386/iscdbx.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Definitions for Intel 386 running Interactive Unix System V, - using dbx-in-coff encapsulation. - Specifically, this is for recent versions that support POSIX. - Copyright (C) 1992, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Mostly it's like AT&T Unix System V with dbx-in-coff. */ - -#include "i386/svr3dbx.h" - -/* But with a few changes. */ -#undef ENDFILE_SPEC -#include "i386/isc.h" - -/* Overridden defines for ifile usage. */ - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC \ - "%{!r:%{!z:svr3.ifile%s}%{z:svr3z.ifile%s}}\ - %{!shlib:%{posix:%{pg:mcrtp1.o%s}%{!pg:%{p:mcrtp1.o%s}%{!p:crtp1.o%s}}}\ - %{Xp:%{pg:mcrtp1.o%s}%{!pg:%{p:mcrtp1.o%s}%{!p:crtp1.o%s}}}\ - %{!posix:%{!Xp:%{pg:mcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}}}\ - %{p:-L/usr/lib/libp} %{pg:-L/usr/lib/libp}}\ - %{shlib:%{posix:crtp1.o%s}%{Xp:crtp1.o%s}%{!posix:%{!Xp:crt1.o%s}}}" - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC "crtn.o%s" diff --git a/support/cpp/i386/linux-aout.h b/support/cpp/i386/linux-aout.h deleted file mode 100644 index 7e46c68b..00000000 --- a/support/cpp/i386/linux-aout.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Definitions for Intel 386 running Linux - Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc. - Contributed by H.J. Lu (hjl@nynexst.com) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This is tested by i386/gas.h. */ -#define YES_UNDERSCORES - -#include -#include /* some common stuff */ - -/* Specify predefined symbols in preprocessor. */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dunix -Di386 -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(i386) -Amachine(i386)" - -#undef CPP_SPEC -#if TARGET_CPU_DEFAULT == 2 -#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{!m386:-D__i486__} %{posix:-D_POSIX_SOURCE}" -#else -#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{m486:-D__i486__} %{posix:-D_POSIX_SOURCE}" -#endif - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "int" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "long int" - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE BITS_PER_WORD - -/* Don't default to pcc-struct-return, because gcc is the only compiler, - and we want to retain compatibility with older gcc versions. */ -#define DEFAULT_PCC_STRUCT_RETURN 0 - -#undef LIB_SPEC - -#if 1 -/* We no longer link with libc_p.a or libg.a by default. If you - * want to profile or debug the Linux C library, please add - * -lc_p or -ggdb to LDFLAGS at the link time, respectively. - */ -#define LIB_SPEC \ -"%{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} %{!ggdb:-lc} %{ggdb:-lg}" -#else -#define LIB_SPEC \ -"%{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} \ - %{!p:%{!pg:%{!g*:-lc} %{g*:-lg -static}}}" -#endif - - -#undef LINK_SPEC -#define LINK_SPEC "-m i386linux" - -/* Get perform_* macros to build libgcc.a. */ -#include "i386/perform.h" diff --git a/support/cpp/i386/linux-oldld.h b/support/cpp/i386/linux-oldld.h deleted file mode 100644 index c3066ba1..00000000 --- a/support/cpp/i386/linux-oldld.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Definitions for Intel 386 running Linux with pre-BFD a.out linkers - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by Michael Meissner (meissner@cygnus.com) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This is tested by i386/gas.h. */ -#define YES_UNDERSCORES - -#include -#include /* some common stuff */ - -/* Specify predefined symbols in preprocessor. */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dunix -Di386 -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(i386) -Amachine(i386)" - -#undef CPP_SPEC -#if TARGET_CPU_DEFAULT == 2 -#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{!m386:-D__i486__} %{posix:-D_POSIX_SOURCE}" -#else -#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{m486:-D__i486__} %{posix:-D_POSIX_SOURCE}" -#endif - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "int" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "long int" - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE BITS_PER_WORD - -/* Don't default to pcc-struct-return, because gcc is the only compiler, - and we want to retain compatibility with older gcc versions. */ -#define DEFAULT_PCC_STRUCT_RETURN 0 - -#undef LIB_SPEC - -#if 1 -/* We no longer link with libc_p.a or libg.a by default. If you - * want to profile or debug the Linux C library, please add - * -lc_p or -ggdb to LDFLAGS at the link time, respectively. - */ -#define LIB_SPEC \ -"%{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} %{!ggdb:-lc} %{ggdb:-lg}" -#else -#define LIB_SPEC \ -"%{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} \ - %{!p:%{!pg:%{!g*:-lc} %{g*:-lg -static}}}" -#endif - - -#undef LINK_SPEC -#define LINK_SPEC "" - -/* Get perform_* macros to build libgcc.a. */ -#include diff --git a/support/cpp/i386/linux.h b/support/cpp/i386/linux.h deleted file mode 100644 index a0b49bab..00000000 --- a/support/cpp/i386/linux.h +++ /dev/null @@ -1,235 +0,0 @@ -/* Definitions for Intel 386 running Linux with ELF format - Copyright (C) 1994, 1995 Free Software Foundation, Inc. - Contributed by Eric Youngdale. - Modified for stabs-in-ELF by H.J. Lu. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define LINUX_DEFAULT_ELF - -/* A lie, I guess, but the general idea behind linux/ELF is that we are - supposed to be outputting something that will assemble under SVr4. - This gets us pretty close. */ -#include /* Base i386 target machine definitions */ -#include /* Use the i386 AT&T assembler syntax */ -#include /* some common stuff */ - -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (i386 Linux/ELF)"); - -/* The svr4 ABI for the i386 says that records and unions are returned - in memory. */ -#undef DEFAULT_PCC_STRUCT_RETURN -#define DEFAULT_PCC_STRUCT_RETURN 1 - -/* This is how to output an element of a case-vector that is relative. - This is only used for PIC code. See comments by the `casesi' insn in - i386.md for an explanation of the expression this outputs. */ -#undef ASM_OUTPUT_ADDR_DIFF_ELT -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ - fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE) - -/* Indicate that jump tables go in the text section. This is - necessary when compiling PIC code. */ -#define JUMP_TABLES_IN_TEXT_SECTION - -/* Copy this from the svr4 specifications... */ -/* Define the register numbers to be used in Dwarf debugging information. - The SVR4 reference port C compiler uses the following register numbers - in its Dwarf output code: - 0 for %eax (gnu regno = 0) - 1 for %ecx (gnu regno = 2) - 2 for %edx (gnu regno = 1) - 3 for %ebx (gnu regno = 3) - 4 for %esp (gnu regno = 7) - 5 for %ebp (gnu regno = 6) - 6 for %esi (gnu regno = 4) - 7 for %edi (gnu regno = 5) - The following three DWARF register numbers are never generated by - the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4 - believes these numbers have these meanings. - 8 for %eip (no gnu equivalent) - 9 for %eflags (no gnu equivalent) - 10 for %trapno (no gnu equivalent) - It is not at all clear how we should number the FP stack registers - for the x86 architecture. If the version of SDB on x86/svr4 were - a bit less brain dead with respect to floating-point then we would - have a precedent to follow with respect to DWARF register numbers - for x86 FP registers, but the SDB on x86/svr4 is so completely - broken with respect to FP registers that it is hardly worth thinking - of it as something to strive for compatibility with. - The version of x86/svr4 SDB I have at the moment does (partially) - seem to believe that DWARF register number 11 is associated with - the x86 register %st(0), but that's about all. Higher DWARF - register numbers don't seem to be associated with anything in - particular, and even for DWARF regno 11, SDB only seems to under- - stand that it should say that a variable lives in %st(0) (when - asked via an `=' command) if we said it was in DWARF regno 11, - but SDB still prints garbage when asked for the value of the - variable in question (via a `/' command). - (Also note that the labels SDB prints for various FP stack regs - when doing an `x' command are all wrong.) - Note that these problems generally don't affect the native SVR4 - C compiler because it doesn't allow the use of -O with -g and - because when it is *not* optimizing, it allocates a memory - location for each floating-point variable, and the memory - location is what gets described in the DWARF AT_location - attribute for the variable in question. - Regardless of the severe mental illness of the x86/svr4 SDB, we - do something sensible here and we use the following DWARF - register numbers. Note that these are all stack-top-relative - numbers. - 11 for %st(0) (gnu regno = 8) - 12 for %st(1) (gnu regno = 9) - 13 for %st(2) (gnu regno = 10) - 14 for %st(3) (gnu regno = 11) - 15 for %st(4) (gnu regno = 12) - 16 for %st(5) (gnu regno = 13) - 17 for %st(6) (gnu regno = 14) - 18 for %st(7) (gnu regno = 15) -*/ -#undef DBX_REGISTER_NUMBER -#define DBX_REGISTER_NUMBER(n) \ -((n) == 0 ? 0 \ - : (n) == 1 ? 2 \ - : (n) == 2 ? 1 \ - : (n) == 3 ? 3 \ - : (n) == 4 ? 6 \ - : (n) == 5 ? 7 \ - : (n) == 6 ? 5 \ - : (n) == 7 ? 4 \ - : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \ - : (-1)) - -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. */ - -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) \ -{ \ - if (flag_pic) \ - { \ - fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \ - LPREFIX, (LABELNO)); \ - fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \ - } \ - else \ - { \ - fprintf (FILE, "\tmovl $%sP%d,%%edx\n", LPREFIX, (LABELNO)); \ - fprintf (FILE, "\tcall mcount\n"); \ - } \ -} - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "int" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "long int" - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE BITS_PER_WORD - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-D__ELF__ -Dunix -Di386 -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(i386) -Amachine(i386)" - -#undef CPP_SPEC -#ifdef USE_GNULIBC_1 -#if TARGET_CPU_DEFAULT == 2 -#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{!m386:-D__i486__} %{posix:-D_POSIX_SOURCE}" -#else -#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{m486:-D__i486__} %{posix:-D_POSIX_SOURCE}" -#endif -#else /* not USE_GNULIBC_1 */ -#define CPP_SPEC "%(cpp_cpu) %[cpp_cpu] %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}" -#endif /* not USE_GNULIBC_1 */ - -#undef LIBGCC_SPEC -#define LIBGCC_SPEC "-lgcc" - -#undef LIB_SPEC -#ifdef USE_GNULIBC_1 -#if 1 -/* We no longer link with libc_p.a or libg.a by default. If you - * want to profile or debug the Linux C library, please add - * -lc_p or -ggdb to LDFLAGS at the link time, respectively. - */ -#define LIB_SPEC \ - "%{!shared: %{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} \ - %{!ggdb:-lc} %{ggdb:-lg}}" -#else -#define LIB_SPEC \ - "%{!shared: \ - %{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} \ - %{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}}" -#endif -#else -#define LIB_SPEC \ - "%{!shared: %{mieee-fp:-lieee} %{pthread:-lpthread} \ - %{profile:-lc_p} %{!profile: -lc}}" -#endif /* not USE_GNULIBC_1 */ - -/* Provide a LINK_SPEC appropriate for Linux. Here we provide support - for the special GCC options -static and -shared, which allow us to - link things in one of these three modes by applying the appropriate - combinations of options at link-time. We like to support here for - as many of the other GNU linker options as possible. But I don't - have the time to search for those flags. I am sure how to add - support for -soname shared_object_name. H.J. - - I took out %{v:%{!V:-V}}. It is too much :-(. They can use - -Wl,-V. - - When the -shared link option is used a final link is not being - done. */ - -/* If ELF is the default format, we should not use /lib/elf. */ - -#undef LINK_SPEC -#ifdef USE_GNULIBC_1 -#ifndef LINUX_DEFAULT_ELF -#define LINK_SPEC "-m elf_i386 %{shared:-shared} \ - %{!shared: \ - %{!ibcs: \ - %{!static: \ - %{rdynamic:-export-dynamic} \ - %{!dynamic-linker:-dynamic-linker /lib/elf/ld-linux.so.1} \ - %{!rpath:-rpath /lib/elf/}} %{static:-static}}}" -#else -#define LINK_SPEC "-m elf_i386 %{shared:-shared} \ - %{!shared: \ - %{!ibcs: \ - %{!static: \ - %{rdynamic:-export-dynamic} \ - %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.1}} \ - %{static:-static}}}" -#endif -#else /* not USE_GNULIBC_1 */ -#define LINK_SPEC "-m elf_i386 %{shared:-shared} \ - %{!shared: \ - %{!ibcs: \ - %{!static: \ - %{rdynamic:-export-dynamic} \ - %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ - %{static:-static}}}" -#endif /* not USE_GNULIBC_1 */ - -/* Get perform_* macros to build libgcc.a. */ -#include "i386/perform.h" diff --git a/support/cpp/i386/lynx-ng.h b/support/cpp/i386/lynx-ng.h deleted file mode 100644 index ec4e2961..00000000 --- a/support/cpp/i386/lynx-ng.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Definitions for Intel 386 running LynxOS, using Lynx's old as and ld. - Copyright (C) 1993, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include -#include - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dunix -Di386 -DI386 -DLynx -DIBITS32 -Asystem(unix) -Asystem(lynx) -Acpu(i386) -Amachine(i386)" - -/* Provide required defaults for linker switches. */ - -#undef LINK_SPEC -#define LINK_SPEC "-P1000 %{msystem-v:-V} %{mcoff:-k}" - -/* Apparently LynxOS clobbers ebx when you call into the OS. */ - -#undef CALL_USED_REGISTERS -#define CALL_USED_REGISTERS \ -/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \ -{ 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } diff --git a/support/cpp/i386/lynx.h b/support/cpp/i386/lynx.h deleted file mode 100644 index 4ac00a05..00000000 --- a/support/cpp/i386/lynx.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Definitions for Intel 386 running LynxOS. - Copyright (C) 1993, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include -#include - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dunix -Di386 -DI386 -DLynx -DIBITS32 -Asystem(unix) -Asystem(lynx) -Acpu(i386) -Amachine(i386)" - -/* This is how to output a reference to a user-level label named NAME. */ - -/* Override the svr3 convention of adding a leading underscore. */ - -#undef ASM_OUTPUT_LABELREF -#define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "%s", NAME) - -/* Apparently LynxOS clobbers ebx when you call into the OS. */ - -#undef CALL_USED_REGISTERS -#define CALL_USED_REGISTERS \ -/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \ -{ 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } diff --git a/support/cpp/i386/mach.h b/support/cpp/i386/mach.h deleted file mode 100644 index 4b7cf37e..00000000 --- a/support/cpp/i386/mach.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Configuration for an i386 running Mach as the target machine. */ - -/* We do want to add an underscore to the front of each user symbol. - i386/gas.h checks this. */ -#define YES_UNDERSCORES - -#include "i386/gstabs.h" - -/* Get perform_* macros to build libgcc.a. */ -#include "i386/perform.h" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dunix -Di386 -DMACH -Asystem(unix) -Asystem(mach) -Acpu(i386) -Amachine(i386)" - -/* Specify extra dir to search for include files. */ -#define SYSTEM_INCLUDE_DIR "/usr/mach/include" - -/* Don't default to pcc-struct-return, because gcc is the only compiler, and - we want to retain compatibility with older gcc versions. */ -#define DEFAULT_PCC_STRUCT_RETURN 0 diff --git a/support/cpp/i386/netbsd.h b/support/cpp/i386/netbsd.h deleted file mode 100644 index 180ff353..00000000 --- a/support/cpp/i386/netbsd.h +++ /dev/null @@ -1,80 +0,0 @@ -/* This goes away when the math-emulator is fixed */ -#define TARGET_CPU_DEFAULT 0400 /* TARGET_NO_FANCY_MATH_387 */ - -/* This is tested by i386gas.h. */ -#define YES_UNDERSCORES - -#include - -/* Get perform_* macros to build libgcc.a. */ -#include - -/* Get generic NetBSD definitions. */ -#include - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dunix -Di386 -D__NetBSD__ -Asystem(unix) -Asystem(NetBSD) -Acpu(i386) -Amachine(i386)" - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "int" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "int" - -#undef WCHAR_UNSIGNED -#define WCHAR_UNSIGNED 0 - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 32 - -#define HANDLE_SYSV_PRAGMA - -/* There are conflicting reports about whether this system uses - a different assembler syntax. wilson@cygnus.com says # is right. */ -#undef COMMENT_BEGIN -#define COMMENT_BEGIN "#" - -#undef ASM_APP_ON -#define ASM_APP_ON "#APP\n" - -#undef ASM_APP_OFF -#define ASM_APP_OFF "#NO_APP\n" - -/* The following macros are stolen from i386v4.h */ -/* These have to be defined to get PIC code correct */ - -/* This is how to output an element of a case-vector that is relative. - This is only used for PIC code. See comments by the `casesi' insn in - i386.md for an explanation of the expression this outputs. */ - -#undef ASM_OUTPUT_ADDR_DIFF_ELT -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ - fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE) - -/* Indicate that jump tables go in the text section. This is - necessary when compiling PIC code. */ - -#define JUMP_TABLES_IN_TEXT_SECTION - -/* Don't default to pcc-struct-return, because gcc is the only compiler, and - we want to retain compatibility with older gcc versions. */ -#define DEFAULT_PCC_STRUCT_RETURN 0 - -/* Profiling routines, partially copied from i386/osfrose.h. */ - -/* Redefine this to use %eax instead of %edx. */ -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) \ -{ \ - if (flag_pic) \ - { \ - fprintf (FILE, "\tcall mcount@PLT\n"); \ - } \ - else \ - { \ - fprintf (FILE, "\tcall mcount\n"); \ - } \ -} diff --git a/support/cpp/i386/next.c b/support/cpp/i386/next.c deleted file mode 100644 index f249647a..00000000 --- a/support/cpp/i386/next.c +++ /dev/null @@ -1,7 +0,0 @@ -/* next.c: Functions for NeXT as target machine for GNU C compiler. */ - -/* Note that the include below means that we can't debug routines in - i386.c when running on a COFF system. */ - -#include "i386/i386.c" -#include "nextstep.c" diff --git a/support/cpp/i386/next.h b/support/cpp/i386/next.h deleted file mode 100644 index c0d6d729..00000000 --- a/support/cpp/i386/next.h +++ /dev/null @@ -1,226 +0,0 @@ -/* Target definitions for GNU compiler for Intel x86 CPU running NeXTSTEP - Copyright (C) 1993, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "i386/gas.h" -#include "nextstep.h" - -/* By default, target has a 80387, with IEEE FP. */ - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (1|0100) - -/* Implicit library calls should use memcpy, not bcopy, etc. */ - -#define TARGET_MEM_FUNCTIONS - -/* Machines that use the AT&T assembler syntax - also return floating point values in an FP register. - Define how to find the value returned by a function. - VALTYPE is the data type of the value (as a tree). - If the precise function being called is known, FUNC is its FUNCTION_DECL; - otherwise, FUNC is 0. */ - -#undef VALUE_REGNO -#define VALUE_REGNO(MODE) \ - ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode \ - ? FIRST_FLOAT_REG : 0) - -/* 1 if N is a possible register number for a function value. */ - -#undef FUNCTION_VALUE_REGNO_P -#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0 || (N)== FIRST_FLOAT_REG) - -#ifdef REAL_VALUE_TO_TARGET_LONG_DOUBLE -#undef ASM_OUTPUT_LONG_DOUBLE -#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ - do { \ - long hex[3]; \ - REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, hex); \ - if (sizeof (int) == sizeof (long)) \ - fprintf (FILE, "\t.long 0x%x\n\t.long 0x%x\n\t.long 0x%x\n", \ - hex[0], hex[1], hex[2]); \ - else \ - fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n\t.long 0x%lx\n", \ - hex[0], hex[1], hex[2]); \ - } while (0) -#endif - -#ifdef REAL_VALUE_TO_TARGET_DOUBLE -#undef ASM_OUTPUT_DOUBLE -#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ - do { \ - long hex[2]; \ - REAL_VALUE_TO_TARGET_DOUBLE (VALUE, hex); \ - if (sizeof (int) == sizeof (long)) \ - fprintf (FILE, "\t.long 0x%x\n\t.long 0x%x\n", hex[0], hex[1]); \ - else \ - fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n", hex[0], hex[1]); \ - } while (0) -#endif - -/* This is how to output an assembler line defining a `float' constant. */ - -#ifdef REAL_VALUE_TO_TARGET_SINGLE -#undef ASM_OUTPUT_FLOAT -#define ASM_OUTPUT_FLOAT(FILE,VALUE) \ - do { \ - long hex; \ - REAL_VALUE_TO_TARGET_SINGLE (VALUE, hex); \ - if (sizeof (int) == sizeof (long)) \ - fprintf (FILE, "\t.long 0x%x\n", hex); \ - else \ - fprintf (FILE, "\t.long 0x%lx\n", hex); \ - } while (0) -#endif - -/* A C statement or statements which output an assembler instruction - opcode to the stdio stream STREAM. The macro-operand PTR is a - variable of type `char *' which points to the opcode name in its - "internal" form--the form that is written in the machine description. - - GAS version 1.38.1 doesn't understand the `repz' opcode mnemonic. - So use `repe' instead. */ - -#undef ASM_OUTPUT_OPCODE -#define ASM_OUTPUT_OPCODE(STREAM, PTR) \ -{ \ - if ((PTR)[0] == 'r' \ - && (PTR)[1] == 'e' \ - && (PTR)[2] == 'p') \ - { \ - if ((PTR)[3] == 'z') \ - { \ - fprintf (STREAM, "repe"); \ - (PTR) += 4; \ - } \ - else if ((PTR)[3] == 'n' && (PTR)[4] == 'z') \ - { \ - fprintf (STREAM, "repne"); \ - (PTR) += 5; \ - } \ - } \ -} - -/* Define macro used to output shift-double opcodes when the shift - count is in %cl. Some assemblers require %cl as an argument; - some don't. - - GAS requires the %cl argument, so override unx386.h. */ - -#undef AS3_SHIFT_DOUBLE -#define AS3_SHIFT_DOUBLE(a,b,c,d) AS3 (a,b,c,d) - -/* Print opcodes the way that GAS expects them. */ -#define GAS_MNEMONICS 1 - -/* Names to predefine in the preprocessor for this target machine. */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Di386 -DNeXT -Dunix -D__MACH__ -D__LITTLE_ENDIAN__ -D__ARCHITECTURE__=\"i386\" -Asystem(unix) -Asystem(mach) -Acpu(i386) -Amachine(i386)" - -/* This accounts for the return pc and saved fp on the i386. */ - -#define OBJC_FORWARDING_STACK_OFFSET 8 -#define OBJC_FORWARDING_MIN_OFFSET 8 - -/* We do not want a dot in internal labels. */ - -#undef LPREFIX -#define LPREFIX "L" - -#undef ASM_GENERATE_INTERNAL_LABEL -#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ - sprintf ((BUF), "*%s%d", (PREFIX), (NUMBER)) - -#undef ASM_OUTPUT_INTERNAL_LABEL -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - fprintf (FILE, "%s%d:\n", PREFIX, NUM) - -/* Output to assembler file text saying following lines - may contain character constants, extra white space, comments, etc. */ - -#undef ASM_APP_ON -#define ASM_APP_ON "#APP\n" - -/* Output to assembler file text saying following lines - no longer contain unusual constructs. */ - -#undef ASM_APP_OFF -#define ASM_APP_OFF "#NO_APP\n" - -#undef ASM_OUTPUT_REG_PUSH -#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ - fprintf (FILE, "\tpushl %se%s\n", "%", reg_names[REGNO]) - -#undef ASM_OUTPUT_REG_POP -#define ASM_OUTPUT_REG_POP(FILE,REGNO) \ - fprintf (FILE, "\tpopl %se%s\n", "%", reg_names[REGNO]) - -/* This is being overridden because the default i386 configuration - generates calls to "_mcount". NeXT system libraries all use - "mcount". */ - -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) \ -{ \ - if (flag_pic) \ - { \ - fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \ - LPREFIX, (LABELNO)); \ - fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \ - } \ - else \ - { \ - fprintf (FILE, "\tmovl $%sP%d,%%edx\n", LPREFIX, (LABELNO)); \ - fprintf (FILE, "\tcall mcount\n"); \ - } \ -} - -/* BEGIN Calling Convention CHANGES */ - -/* These changes violate the Intel/Unix ABI. Specifically, they - change the way that space for a block return value is passed to a - function. The ABI says that the pointer is passed on the stack. - We change to pass the pointer in %ebx. This makes the NeXT - Objective-C forwarding mechanism possible to implement on an i386. */ - -/* Do NOT pass address of structure values on the stack. */ - -#undef STRUCT_VALUE_INCOMING -#undef STRUCT_VALUE - -/* Pass them in %ebx. */ - -#undef STRUCT_VALUE_REGNUM -#define STRUCT_VALUE_REGNUM 3 - -/* Because we are passing the pointer in a register, we don't need to - rely on the callee to pop it. */ - -#undef RETURN_POPS_ARGS -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \ - (TREE_CODE (FUNTYPE) == IDENTIFIER_NODE \ - ? 0 \ - : (TARGET_RTD \ - && (TYPE_ARG_TYPES (FUNTYPE) == 0 \ - || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ - == void_type_node))) ? (SIZE) : 0) - -/* END Calling Convention CHANGES */ diff --git a/support/cpp/i386/os2.h b/support/cpp/i386/os2.h deleted file mode 100644 index 8bbab361..00000000 --- a/support/cpp/i386/os2.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Definitions of target machine for GNU compiler - for an Intel i386 or later processor running OS/2 2.x. - Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. - Contributed by Samuel Figueroa (figueroa@cs.nyu.edu) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifndef DEFAULT_TARGET_MACHINE -#define DEFAULT_TARGET_MACHINE "i386-os2" -#endif -#ifndef LINK_SPEC -#define LINK_SPEC "/st:1048576/pm:vio/noi/a:16/e/bas:65536/nol" -#endif -#ifndef LIB_SPEC -#define LIB_SPEC "libgcc libc" -#endif -#ifndef STARTFILE_SPEC -#define STARTFILE_SPEC "libcrt.lib" -#endif -#ifndef MD_EXEC_PREFIX -#define MD_EXEC_PREFIX "\\gcc\\bin\\" -#endif -#ifndef STANDARD_STARTFILE_PREFIX -#define STANDARD_STARTFILE_PREFIX "\\gcc\\lib\\" -#endif -#ifndef LOCAL_INCLUDE_DIR -#define LOCAL_INCLUDE_DIR "\\gcc\\include" -#endif - -#define YES_UNDERSCORES -#include "i386/gstabs.h" - -#define USE_COLLECT - -#define BIGGEST_FIELD_ALIGNMENT \ - (maximum_field_alignment ? maximum_field_alignment : 32) - -extern int maximum_field_alignment; - -#undef PCC_BITFIELD_TYPE_MATTERS -#define PCC_BITFIELD_TYPE_MATTERS (maximum_field_alignment == 0) - -/* Define this macro if it is advisable to hold scalars in registers - in a wider mode than that declared by the program. In such cases, - the value is constrained to be within the bounds of the declared - type, but kept valid in the wider mode. The signedness of the - extension may differ from that of the type. */ - -#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \ - if (GET_MODE_CLASS (MODE) == MODE_INT \ - && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \ - (MODE) = SImode; - -/* Define this if function arguments should also be promoted using the above - procedure. */ - -#define PROMOTE_FUNCTION_ARGS - -/* Likewise, if the function return value is promoted. */ - -#define PROMOTE_FUNCTION_RETURN diff --git a/support/cpp/i386/osfelf.h b/support/cpp/i386/osfelf.h deleted file mode 100644 index 7e71fe98..00000000 --- a/support/cpp/i386/osfelf.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Definitions of target machine for GNU compiler. - Intel 386 (OSF/1 with ELF) version. - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config/i386/osfrose.h" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-DOSF -DOSF1 -Dunix -Di386 -Asystem(unix) -Asystem(xpg4) -Acpu(i386) -Amachine(i386)" - -#undef CPP_SPEC -#define CPP_SPEC "\ -%{mrose: -D__ROSE__ %{!pic-none: -D__SHARED__}} \ -%{!mrose: -D__ELF__ %{fpic: -D__SHARED__}} \ -%{mno-underscores: -D__NO_UNDERSCORES__} \ -%{!mrose: %{!munderscores: -D__NO_UNDERSCORES__}} \ -%{.S: %{!ansi:%{!traditional:%{!traditional-cpp:%{!ftraditional: -traditional}}}}} \ -%{.S: -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ -%{.cc: -D__LANGUAGE_C_PLUS_PLUS} \ -%{.cxx: -D__LANGUAGE_C_PLUS_PLUS} \ -%{.C: -D__LANGUAGE_C_PLUS_PLUS} \ -%{.m: -D__LANGUAGE_OBJECTIVE_C} \ -%{!.S: -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" - -/* Turn on -pic-extern by default for OSF/rose, -fpic for ELF. */ -#undef CC1_SPEC -#define CC1_SPEC "\ -%{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \ -%{!melf: %{!mrose: -melf }} \ -%{!mrose: %{!munderscores: %{!mno-underscores: -mno-underscores }} \ - %{!mmcount: %{!mno-mcount: %{!mmcount-ptr: -mmcount-ptr }}}} \ -%{mrose: %{!mmcount: %{!mno-mcount: %{!mmcount-ptr: -mmcount }}} \ - %{pic-extern: -mhalf-pic } %{pic-lib: -mhalf-pic } \ - %{!pic-extern: %{!pic-lib: %{pic-none: -mno-half-pic} %{!pic-none: -mhalf-pic}}} \ - %{pic-calls: } %{pic-names*: }}" - -#undef ASM_SPEC -#define ASM_SPEC "%{v*: -v}" - -#undef LINK_SPEC -#define LINK_SPEC "%{v*: -v} \ -%{mrose: %{!noshrlib: %{pic-none: -noshrlib} %{!pic-none: -warn_nopic}} \ - %{nostdlib} %{noshrlib} %{glue}} \ -%{!mrose: %{dy} %{dn} %{glue: } \ - %{h*} %{z*} \ - %{static:-dn -Bstatic} \ - %{shared:-G -dy} \ - %{symbolic:-Bsymbolic -G -dy} \ - %{G:-G} \ - %{!dy: %{!dn: %{!static: %{!shared: %{!symbolic: \ - %{noshrlib: -dn } %{pic-none: -dn } \ - %{!noshrlib: %{!pic-none: -dy}}}}}}}}" - -#undef TARGET_VERSION_INTERNAL -#undef TARGET_VERSION - -#undef I386_VERSION -#define I386_VERSION " 80386, ELF objects" - -#define TARGET_VERSION_INTERNAL(STREAM) fputs (I386_VERSION, STREAM) -#define TARGET_VERSION TARGET_VERSION_INTERNAL (stderr) - -#undef OBJECT_FORMAT_ROSE diff --git a/support/cpp/i386/osfrose.h b/support/cpp/i386/osfrose.h deleted file mode 100644 index 3aae1e1b..00000000 --- a/support/cpp/i386/osfrose.h +++ /dev/null @@ -1,923 +0,0 @@ -/* Definitions of target machine for GNU compiler. - Intel 386 (OSF/1 with OSF/rose) version. - Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "halfpic.h" -#include "i386/gstabs.h" - -/* Get perform_* macros to build libgcc.a. */ -#include "i386/perform.h" - -#define OSF_OS - -#undef WORD_SWITCH_TAKES_ARG -#define WORD_SWITCH_TAKES_ARG(STR) \ - (DEFAULT_WORD_SWITCH_TAKES_ARG (STR) || !strcmp (STR, "pic-names")) - -/* This defines which switch letters take arguments. On svr4, most of - the normal cases (defined in gcc.c) apply, and we also have -h* and - -z* options (for the linker). */ - -#define SWITCH_TAKES_ARG(CHAR) \ - ( (CHAR) == 'D' \ - || (CHAR) == 'U' \ - || (CHAR) == 'o' \ - || (CHAR) == 'e' \ - || (CHAR) == 'T' \ - || (CHAR) == 'u' \ - || (CHAR) == 'I' \ - || (CHAR) == 'm' \ - || (CHAR) == 'L' \ - || (CHAR) == 'A' \ - || (CHAR) == 'h' \ - || (CHAR) == 'z') - -#define MASK_HALF_PIC 010000000000 /* Mask for half-pic code */ -#define MASK_HALF_PIC_DEBUG 004000000000 /* Debug flag */ -#define MASK_ELF 002000000000 /* ELF not rose */ -#define MASK_NO_IDENT 001000000000 /* suppress .ident */ -#define MASK_NO_UNDERSCORES 000400000000 /* suppress leading _ */ -#define MASK_LARGE_ALIGN 000200000000 /* align to >word boundaries */ -#define MASK_NO_MCOUNT 000100000000 /* profiling uses mcount_ptr */ - -#define TARGET_HALF_PIC (target_flags & MASK_HALF_PIC) -#define TARGET_DEBUG (target_flags & MASK_HALF_PIC_DEBUG) -#define HALF_PIC_DEBUG TARGET_DEBUG -#define TARGET_ELF (target_flags & MASK_ELF) -#define TARGET_ROSE ((target_flags & MASK_ELF) == 0) -#define TARGET_IDENT ((target_flags & MASK_NO_IDENT) == 0) -#define TARGET_UNDERSCORES ((target_flags & MASK_NO_UNDERSCORES) == 0) -#define TARGET_LARGE_ALIGN (target_flags & MASK_LARGE_ALIGN) -#define TARGET_MCOUNT ((target_flags & MASK_NO_MCOUNT) == 0) - -#undef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES \ - { "half-pic", MASK_HALF_PIC}, \ - { "no-half-pic", -MASK_HALF_PIC}, \ - { "debug-half-pic", MASK_HALF_PIC_DEBUG}, \ - { "debugb", MASK_HALF_PIC_DEBUG}, \ - { "elf", MASK_ELF}, \ - { "rose", -MASK_ELF}, \ - { "ident", -MASK_NO_IDENT}, \ - { "no-ident", MASK_NO_IDENT}, \ - { "underscores", -MASK_NO_UNDERSCORES}, \ - { "no-underscores", MASK_NO_UNDERSCORES}, \ - { "large-align", MASK_LARGE_ALIGN}, \ - { "no-large-align", -MASK_LARGE_ALIGN}, \ - { "mcount", -MASK_NO_MCOUNT}, \ - { "mcount-ptr", MASK_NO_MCOUNT}, \ - { "no-mcount", MASK_NO_MCOUNT}, - -/* OSF/rose uses stabs, not dwarf. */ -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG - -#ifndef DWARF_DEBUGGING_INFO -#define DWARF_DEBUGGING_INFO /* enable dwarf debugging for testing */ -#endif - -/* Handle #pragma weak and #pragma pack. */ - -#define HANDLE_SYSV_PRAGMA -#define SUPPORTS_WEAK TARGET_ELF - -/* Change default predefines. */ -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-DOSF -DOSF1 -Dunix -Di386 -Asystem(unix) -Asystem(xpg4) -Acpu(i386) -Amachine(i386)" - -#undef CPP_SPEC -#define CPP_SPEC "\ -%{!melf: -D__ROSE__ %{!pic-none: -D__SHARED__}} \ -%{melf: -D__ELF__ %{fpic: -D__SHARED__}} \ -%{mno-underscores: -D__NO_UNDERSCORES__} \ -%{melf: %{!munderscores: -D__NO_UNDERSCORES__}} \ -%{.S: %{!ansi:%{!traditional:%{!traditional-cpp:%{!ftraditional: -traditional}}}}} \ -%{.S: -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ -%{.cc: -D__LANGUAGE_C_PLUS_PLUS} \ -%{.cxx: -D__LANGUAGE_C_PLUS_PLUS} \ -%{.C: -D__LANGUAGE_C_PLUS_PLUS} \ -%{.m: -D__LANGUAGE_OBJECTIVE_C} \ -%{!.S: -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" - -/* Turn on -pic-extern by default for OSF/rose, -fpic for ELF. */ -#undef CC1_SPEC -#define CC1_SPEC "\ -%{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \ -%{!melf: %{!mrose: -mrose }} \ -%{melf: %{!munderscores: %{!mno-underscores: -mno-underscores }} \ - %{!mmcount: %{!mno-mcount: %{!mmcount-ptr: -mmcount-ptr }}}} \ -%{!melf: %{!munderscores: %{!mno-underscores: -munderscores }} \ - %{!mmcount: %{!mno-mcount: %{!mmcount-ptr: -mmcount }}} \ - %{pic-extern: -mhalf-pic } %{pic-lib: -mhalf-pic } \ - %{!pic-extern: %{!pic-lib: %{pic-none: -mno-half-pic} %{!pic-none: -mhalf-pic}}} \ - %{pic-calls: } %{pic-names*: }}" - -#undef ASM_SPEC -#define ASM_SPEC "%{v*: -v}" - -#undef LINK_SPEC -#define LINK_SPEC "%{v*: -v} \ -%{!melf: %{!noshrlib: %{pic-none: -noshrlib} %{!pic-none: -warn_nopic}} \ - %{nostdlib} %{noshrlib} %{glue}} \ -%{melf: %{dy} %{dn} %{glue: } \ - %{h*} %{z*} \ - %{static:-dn -Bstatic} \ - %{shared:-G -dy} \ - %{symbolic:-Bsymbolic -G -dy} \ - %{G:-G} \ - %{!dy: %{!dn: %{!static: %{!shared: %{!symbolic: \ - %{noshrlib: -dn } %{pic-none: -dn } \ - %{!noshrlib: %{!pic-none: -dy}}}}}}}}" - -#undef LIB_SPEC -#define LIB_SPEC "-lc" - -#undef LIBG_SPEC -#define LIBG_SPEC "" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}" - -#undef TARGET_VERSION_INTERNAL -#undef TARGET_VERSION - -#define I386_VERSION " 80386, OSF/rose objects" - -#define TARGET_VERSION_INTERNAL(STREAM) fputs (I386_VERSION, STREAM) -#define TARGET_VERSION TARGET_VERSION_INTERNAL (stderr) - -#undef MD_EXEC_PREFIX -#define MD_EXEC_PREFIX "/usr/ccs/gcc/" - -#undef MD_STARTFILE_PREFIX -#define MD_STARTFILE_PREFIX "/usr/ccs/lib/" - -/* Specify size_t, ptrdiff_t, and wchar_t types. */ -#undef SIZE_TYPE -#undef PTRDIFF_TYPE -#undef WCHAR_TYPE -#undef WCHAR_TYPE_SIZE - -#define SIZE_TYPE "long unsigned int" -#define PTRDIFF_TYPE "int" -#define WCHAR_TYPE "unsigned int" -#define WCHAR_TYPE_SIZE BITS_PER_WORD - -/* Define this macro if the system header files support C++ as well - as C. This macro inhibits the usual method of using system header - files in C++, which is to pretend that the file's contents are - enclosed in `extern "C" {...}'. */ -#define NO_IMPLICIT_EXTERN_C - -/* Turn off long double being 96 bits. */ -#undef LONG_DOUBLE_TYPE_SIZE -#define LONG_DOUBLE_TYPE_SIZE 64 - -/* This macro generates the assembly code for function entry. - FILE is a stdio stream to output the code to. - SIZE is an int: how many units of temporary storage to allocate. - Refer to the array `regs_ever_live' to determine which registers - to save; `regs_ever_live[I]' is nonzero if register number I - is ever used in the function. This macro is responsible for - knowing which registers should not be saved even if used. - - We override it here to allow for the new profiling code to go before - the prologue and the old mcount code to go after the prologue (and - after %ebx has been set up for ELF shared library support). */ - -#define OSF_PROFILE_BEFORE_PROLOGUE \ - (!TARGET_MCOUNT \ - && !current_function_needs_context \ - && (!flag_pic \ - || !frame_pointer_needed \ - || (!current_function_uses_pic_offset_table \ - && !current_function_uses_const_pool))) - -#undef FUNCTION_PROLOGUE -#define FUNCTION_PROLOGUE(FILE, SIZE) \ -do \ - { \ - char *prefix = (TARGET_UNDERSCORES) ? "_" : ""; \ - char *lprefix = LPREFIX; \ - int labelno = profile_label_no; \ - \ - if (profile_flag && OSF_PROFILE_BEFORE_PROLOGUE) \ - { \ - if (!flag_pic && !HALF_PIC_P ()) \ - { \ - fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ - fprintf (FILE, "\tcall *%s_mcount_ptr\n", prefix); \ - } \ - \ - else if (HALF_PIC_P ()) \ - { \ - rtx symref; \ - \ - HALF_PIC_EXTERNAL ("_mcount_ptr"); \ - symref = HALF_PIC_PTR (gen_rtx (SYMBOL_REF, Pmode, \ - "_mcount_ptr")); \ - \ - fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ - fprintf (FILE, "\tmovl %s%s,%%eax\n", prefix, \ - XSTR (symref, 0)); \ - fprintf (FILE, "\tcall *(%%eax)\n"); \ - } \ - \ - else \ - { \ - static int call_no = 0; \ - \ - fprintf (FILE, "\tcall %sPc%d\n", lprefix, call_no); \ - fprintf (FILE, "%sPc%d:\tpopl %%eax\n", lprefix, call_no); \ - fprintf (FILE, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-%sPc%d],%%eax\n", \ - lprefix, call_no++); \ - fprintf (FILE, "\tleal %sP%d@GOTOFF(%%eax),%%edx\n", \ - lprefix, labelno); \ - fprintf (FILE, "\tmovl %s_mcount_ptr@GOT(%%eax),%%eax\n", \ - prefix); \ - fprintf (FILE, "\tcall *(%%eax)\n"); \ - } \ - } \ - \ - function_prologue (FILE, SIZE); \ - } \ -while (0) - -/* A C statement or compound statement to output to FILE some assembler code to - call the profiling subroutine `mcount'. Before calling, the assembler code - must load the address of a counter variable into a register where `mcount' - expects to find the address. The name of this variable is `LP' followed by - the number LABELNO, so you would generate the name using `LP%d' in a - `fprintf'. - - The details of how the address should be passed to `mcount' are determined - by your operating system environment, not by GNU CC. To figure them out, - compile a small program for profiling using the system's installed C - compiler and look at the assembler code that results. */ - -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) \ -do \ - { \ - if (!OSF_PROFILE_BEFORE_PROLOGUE) \ - { \ - char *prefix = (TARGET_UNDERSCORES) ? "_" : ""; \ - char *lprefix = LPREFIX; \ - int labelno = LABELNO; \ - \ - /* Note that OSF/rose blew it in terms of calling mcount, \ - since OSF/rose prepends a leading underscore, but mcount's \ - doesn't. At present, we keep this kludge for ELF as well \ - to allow old kernels to build profiling. */ \ - \ - if (flag_pic \ - && !current_function_uses_pic_offset_table \ - && !current_function_uses_const_pool) \ - abort (); \ - \ - if (TARGET_MCOUNT && flag_pic) \ - { \ - fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \ - lprefix, labelno); \ - fprintf (FILE, "\tcall *%smcount@GOT(%%ebx)\n", prefix); \ - } \ - \ - else if (TARGET_MCOUNT && HALF_PIC_P ()) \ - { \ - rtx symdef; \ - \ - HALF_PIC_EXTERNAL ("mcount"); \ - symdef = HALF_PIC_PTR (gen_rtx (SYMBOL_REF, Pmode, "mcount")); \ - fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ - fprintf (FILE, "\tcall *%s%s\n", prefix, XSTR (symdef, 0)); \ - } \ - \ - else if (TARGET_MCOUNT) \ - { \ - fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ - fprintf (FILE, "\tcall %smcount\n", prefix); \ - } \ - \ - else if (flag_pic && frame_pointer_needed) \ - { \ - fprintf (FILE, "\tmovl 4(%%ebp),%%ecx\n"); \ - fprintf (FILE, "\tpushl %%ecx\n"); \ - fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \ - lprefix, labelno); \ - fprintf (FILE, "\tmovl _mcount_ptr@GOT(%%ebx),%%eax\n"); \ - fprintf (FILE, "\tcall *(%%eax)\n"); \ - fprintf (FILE, "\tpopl %%eax\n"); \ - } \ - \ - else if (frame_pointer_needed) \ - { \ - fprintf (FILE, "\tmovl 4(%%ebp),%%ecx\n"); \ - fprintf (FILE, "\tpushl %%ecx\n"); \ - fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ - fprintf (FILE, "\tcall *_mcount_ptr\n"); \ - fprintf (FILE, "\tpopl %%eax\n"); \ - } \ - \ - else \ - abort (); \ - } \ - } \ -while (0) - -/* A C function or functions which are needed in the library to - support block profiling. When support goes into libc, undo - the #if 0. */ - -#if 0 -#undef BLOCK_PROFILING_CODE -#define BLOCK_PROFILING_CODE -#endif - -/* Prefix for internally generated assembler labels. If we aren't using - underscores, we are using prefix `.'s to identify labels that should - be ignored, as in `i386/gas.h' --karl@cs.umb.edu */ -#undef LPREFIX -#define LPREFIX ((TARGET_UNDERSCORES) ? "L" : ".L") - -/* This is how to store into the string BUF - the symbol_ref name of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. */ - -#undef ASM_GENERATE_INTERNAL_LABEL -#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ - sprintf ((BUF), "*%s%s%d", (TARGET_UNDERSCORES) ? "" : ".", \ - (PREFIX), (NUMBER)) - -/* This is how to output an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. */ - -#undef ASM_OUTPUT_INTERNAL_LABEL -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - fprintf (FILE, "%s%s%d:\n", (TARGET_UNDERSCORES) ? "" : ".", \ - PREFIX, NUM) - -/* This is how to output a reference to a user-level label named NAME. */ - -#undef ASM_OUTPUT_LABELREF -#define ASM_OUTPUT_LABELREF(FILE,NAME) \ - fprintf (FILE, "%s%s", (TARGET_UNDERSCORES) ? "_" : "", NAME) - -/* This is how to output an element of a case-vector that is relative. - This is only used for PIC code. See comments by the `casesi' insn in - i386.md for an explanation of the expression this outputs. */ - -#undef ASM_OUTPUT_ADDR_DIFF_ELT -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ - fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE) - -/* Output a definition */ -#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \ -do \ -{ \ - fprintf ((FILE), "\t%s\t", SET_ASM_OP); \ - assemble_name (FILE, LABEL1); \ - fprintf (FILE, ","); \ - assemble_name (FILE, LABEL2); \ - fprintf (FILE, "\n"); \ - } \ -while (0) - -/* A C expression to output text to align the location counter in the - way that is desirable at a point in the code that is reached only - by jumping. - - This macro need not be defined if you don't want any special - alignment to be done at such a time. Most machine descriptions do - not currently define the macro. */ - -#undef ASM_OUTPUT_ALIGN_CODE -#define ASM_OUTPUT_ALIGN_CODE(STREAM) \ - fprintf (STREAM, "\t.align\t%d\n", \ - (!TARGET_LARGE_ALIGN && i386_align_jumps > 2) ? 2 : i386_align_jumps) - -/* A C expression to output text to align the location counter in the - way that is desirable at the beginning of a loop. - - This macro need not be defined if you don't want any special - alignment to be done at such a time. Most machine descriptions do - not currently define the macro. */ - -#undef ASM_OUTPUT_LOOP_ALIGN -#define ASM_OUTPUT_LOOP_ALIGN(STREAM) \ - fprintf (STREAM, "\t.align\t%d\n", i386_align_loops) - -/* A C statement to output to the stdio stream STREAM an assembler - command to advance the location counter to a multiple of 2 to the - POWER bytes. POWER will be a C expression of type `int'. */ - -#undef ASM_OUTPUT_ALIGN -#define ASM_OUTPUT_ALIGN(STREAM, POWER) \ - fprintf (STREAM, "\t.align\t%d\n", \ - (!TARGET_LARGE_ALIGN && (POWER) > 2) ? 2 : (POWER)) - -/* A C expression that is 1 if the RTX X is a constant which is a - valid address. On most machines, this can be defined as - `CONSTANT_P (X)', but a few machines are more restrictive in - which constant addresses are supported. - - `CONSTANT_P' accepts integer-values expressions whose values are - not explicitly known, such as `symbol_ref', `label_ref', and - `high' expressions and `const' arithmetic expressions, in - addition to `const_int' and `const_double' expressions. */ - -#define CONSTANT_ADDRESS_P_ORIG(X) \ - (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ - || GET_CODE (X) == HIGH) - -#undef CONSTANT_ADDRESS_P -#define CONSTANT_ADDRESS_P(X) \ - ((CONSTANT_ADDRESS_P_ORIG (X)) && (!HALF_PIC_P () || !HALF_PIC_ADDRESS_P (X))) - -/* Nonzero if the constant value X is a legitimate general operand. - It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ - -#undef LEGITIMATE_CONSTANT_P -#define LEGITIMATE_CONSTANT_P(X) \ - (!HALF_PIC_P () \ - || GET_CODE (X) == CONST_DOUBLE \ - || GET_CODE (X) == CONST_INT \ - || !HALF_PIC_ADDRESS_P (X)) - -/* Sometimes certain combinations of command options do not make sense - on a particular target machine. You can define a macro - `OVERRIDE_OPTIONS' to take account of this. This macro, if - defined, is executed once just after all the command options have - been parsed. */ - -#undef SUBTARGET_OVERRIDE_OPTIONS -#define SUBTARGET_OVERRIDE_OPTIONS \ -{ \ - /* \ - if (TARGET_ELF && TARGET_HALF_PIC) \ - { \ - target_flags &= ~MASK_HALF_PIC; \ - flag_pic = 1; \ - } \ - */ \ - \ - if (TARGET_ROSE && flag_pic) \ - { \ - target_flags |= MASK_HALF_PIC; \ - flag_pic = 0; \ - } \ - \ - if (TARGET_HALF_PIC) \ - half_pic_init (); \ -} - -/* Define this macro if references to a symbol must be treated - differently depending on something about the variable or - function named by the symbol (such as what section it is in). - - The macro definition, if any, is executed immediately after the - rtl for DECL has been created and stored in `DECL_RTL (DECL)'. - The value of the rtl will be a `mem' whose address is a - `symbol_ref'. - - The usual thing for this macro to do is to a flag in the - `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified - name string in the `symbol_ref' (if one bit is not enough - information). - - The best way to modify the name string is by adding text to the - beginning, with suitable punctuation to prevent any ambiguity. - Allocate the new name in `saveable_obstack'. You will have to - modify `ASM_OUTPUT_LABELREF' to remove and decode the added text - and output the name accordingly. - - You can also check the information stored in the `symbol_ref' in - the definition of `GO_IF_LEGITIMATE_ADDRESS' or - `PRINT_OPERAND_ADDRESS'. */ - -#undef ENCODE_SECTION_INFO -#define ENCODE_SECTION_INFO(DECL) \ -do \ - { \ - if (HALF_PIC_P ()) \ - HALF_PIC_ENCODE (DECL); \ - \ - else if (flag_pic) \ - { \ - rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ - ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \ - SYMBOL_REF_FLAG (XEXP (rtl, 0)) \ - = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ - || ! TREE_PUBLIC (DECL)); \ - } \ - } \ -while (0) - - -/* On most machines, read-only variables, constants, and jump tables - are placed in the text section. If this is not the case on your - machine, this macro should be defined to be the name of a function - (either `data_section' or a function defined in `EXTRA_SECTIONS') - that switches to the section to be used for read-only items. - - If these items should be placed in the text section, this macro - should not be defined. */ - -#if 0 -#undef READONLY_DATA_SECTION -#define READONLY_DATA_SECTION() \ -do \ - { \ - if (TARGET_ELF) \ - { \ - if (in_section != in_rodata) \ - { \ - fprintf (asm_out_file, "\t.section \"rodata\"\n"); \ - in_section = in_rodata; \ - } \ - } \ - else \ - text_section (); \ - } \ -while (0) -#endif - -/* A list of names for sections other than the standard two, which are - `in_text' and `in_data'. You need not define this macro on a - system with no other sections (that GCC needs to use). */ - -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_rodata, in_data1 - -/* Given a decl node or constant node, choose the section to output it in - and select that section. */ - -#undef SELECT_RTX_SECTION -#define SELECT_RTX_SECTION(MODE, RTX) \ -do \ - { \ - if (MODE == Pmode && HALF_PIC_P () && HALF_PIC_ADDRESS_P (RTX)) \ - data_section (); \ - else \ - readonly_data_section (); \ - } \ -while (0) - -#undef SELECT_SECTION -#define SELECT_SECTION(DECL, RELOC) \ -{ \ - if (RELOC && HALF_PIC_P ()) \ - data_section (); \ - \ - else if (TREE_CODE (DECL) == STRING_CST) \ - { \ - if (flag_writable_strings) \ - data_section (); \ - else \ - readonly_data_section (); \ - } \ - \ - else if (TREE_CODE (DECL) != VAR_DECL) \ - readonly_data_section (); \ - \ - else if (!TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \ - || !DECL_INITIAL (DECL) \ - || (DECL_INITIAL (DECL) != error_mark_node \ - && !TREE_CONSTANT (DECL_INITIAL (DECL)))) \ - data_section (); \ - \ - else \ - readonly_data_section (); \ -} - - -/* Define the strings used for the special svr4 .type and .size directives. - These strings generally do not vary from one system running svr4 to - another, but if a given system (e.g. m88k running svr) needs to use - different pseudo-op names for these, they may be overridden in the - file which includes this one. */ - -#define TYPE_ASM_OP ".type" -#define SIZE_ASM_OP ".size" -#define SET_ASM_OP ".set" - -/* This is how we tell the assembler that a symbol is weak. */ - -#define ASM_WEAKEN_LABEL(FILE,NAME) \ - do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \ - fputc ('\n', FILE); } while (0) - -/* The following macro defines the format used to output the second - operand of the .type assembler directive. Different svr4 assemblers - expect various different forms for this operand. The one given here - is just a default. You may need to override it in your machine- - specific tm.h file (depending upon the particulars of your assembler). */ - -#define TYPE_OPERAND_FMT "@%s" - -/* A C statement (sans semicolon) to output to the stdio stream - STREAM any text necessary for declaring the name NAME of an - initialized variable which is being defined. This macro must - output the label definition (perhaps using `ASM_OUTPUT_LABEL'). - The argument DECL is the `VAR_DECL' tree node representing the - variable. - - If this macro is not defined, then the variable name is defined - in the usual manner as a label (by means of `ASM_OUTPUT_LABEL'). */ - -#undef ASM_DECLARE_OBJECT_NAME -#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \ -do \ - { \ - ASM_OUTPUT_LABEL(STREAM,NAME); \ - HALF_PIC_DECLARE (NAME); \ - if (TARGET_ELF) \ - { \ - fprintf (STREAM, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (STREAM, NAME); \ - putc (',', STREAM); \ - fprintf (STREAM, TYPE_OPERAND_FMT, "object"); \ - putc ('\n', STREAM); \ - size_directive_output = 0; \ - if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \ - { \ - size_directive_output = 1; \ - fprintf (STREAM, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (STREAM, NAME); \ - fprintf (STREAM, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ - } \ - } \ - } \ -while (0) - -/* Output the size directive for a decl in rest_of_decl_compilation - in the case where we did not do so before the initializer. - Once we find the error_mark_node, we know that the value of - size_directive_output was set - by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ - -#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ -do { \ - char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ - if (TARGET_ELF \ - && !flag_inhibit_size_directive && DECL_SIZE (DECL) \ - && ! AT_END && TOP_LEVEL \ - && DECL_INITIAL (DECL) == error_mark_node \ - && !size_directive_output) \ - { \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, name); \ - fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ - } \ - } while (0) - -/* This is how to declare a function name. */ - -#undef ASM_DECLARE_FUNCTION_NAME -#define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL) \ -do \ - { \ - ASM_OUTPUT_LABEL(STREAM,NAME); \ - HALF_PIC_DECLARE (NAME); \ - if (TARGET_ELF) \ - { \ - fprintf (STREAM, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (STREAM, NAME); \ - putc (',', STREAM); \ - fprintf (STREAM, TYPE_OPERAND_FMT, "function"); \ - putc ('\n', STREAM); \ - ASM_DECLARE_RESULT (STREAM, DECL_RESULT (DECL)); \ - } \ - } \ -while (0) - -/* Write the extra assembler code needed to declare a function's result. - Most svr4 assemblers don't require any special declaration of the - result value, but there are exceptions. */ - -#ifndef ASM_DECLARE_RESULT -#define ASM_DECLARE_RESULT(FILE, RESULT) -#endif - -/* This is how to declare the size of a function. */ - -#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ -do \ - { \ - if (TARGET_ELF && !flag_inhibit_size_directive) \ - { \ - char label[256]; \ - static int labelno; \ - labelno++; \ - ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \ - ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, (FNAME)); \ - fprintf (FILE, ","); \ - assemble_name (FILE, label); \ - fprintf (FILE, "-"); \ - assemble_name (FILE, (FNAME)); \ - putc ('\n', FILE); \ - } \ - } \ -while (0) - -/* Attach a special .ident directive to the end of the file to identify - the version of GCC which compiled this code. The format of the - .ident string is patterned after the ones produced by native svr4 - C compilers. */ - -#define IDENT_ASM_OP ".ident" - -/* Allow #sccs in preprocessor. */ - -#define SCCS_DIRECTIVE - -/* This says what to print at the end of the assembly file */ -#define ASM_FILE_END(STREAM) \ -do \ - { \ - if (HALF_PIC_P ()) \ - HALF_PIC_FINISH (STREAM); \ - \ - if (TARGET_IDENT) \ - { \ - char *fstart = main_input_filename; \ - char *fname; \ - \ - if (!fstart) \ - fstart = ""; \ - \ - fname = fstart + strlen (fstart) - 1; \ - while (fname > fstart && *fname != '/') \ - fname--; \ - \ - if (*fname == '/') \ - fname++; \ - \ - fprintf ((STREAM), "\t%s\t\"GCC: (GNU) %s %s -O%d", \ - IDENT_ASM_OP, version_string, fname, optimize); \ - \ - if (write_symbols == PREFERRED_DEBUGGING_TYPE) \ - fprintf ((STREAM), " -g%d", (int)debug_info_level); \ - \ - else if (write_symbols == DBX_DEBUG) \ - fprintf ((STREAM), " -gstabs%d", (int)debug_info_level); \ - \ - else if (write_symbols == DWARF_DEBUG) \ - fprintf ((STREAM), " -gdwarf%d", (int)debug_info_level); \ - \ - else if (write_symbols != NO_DEBUG) \ - fprintf ((STREAM), " -g??%d", (int)debug_info_level); \ - \ - if (flag_omit_frame_pointer) \ - fprintf ((STREAM), " -fomit-frame-pointer"); \ - \ - if (flag_strength_reduce) \ - fprintf ((STREAM), " -fstrength-reduce"); \ - \ - if (flag_unroll_loops) \ - fprintf ((STREAM), " -funroll-loops"); \ - \ - if (flag_schedule_insns) \ - fprintf ((STREAM), " -fschedule-insns"); \ - \ - if (flag_schedule_insns_after_reload) \ - fprintf ((STREAM), " -fschedule-insns2"); \ - \ - if (flag_force_mem) \ - fprintf ((STREAM), " -fforce-mem"); \ - \ - if (flag_force_addr) \ - fprintf ((STREAM), " -fforce-addr"); \ - \ - if (flag_inline_functions) \ - fprintf ((STREAM), " -finline-functions"); \ - \ - if (flag_caller_saves) \ - fprintf ((STREAM), " -fcaller-saves"); \ - \ - if (flag_pic) \ - fprintf ((STREAM), (flag_pic > 1) ? " -fPIC" : " -fpic"); \ - \ - if (flag_inhibit_size_directive) \ - fprintf ((STREAM), " -finhibit-size-directive"); \ - \ - if (flag_gnu_linker) \ - fprintf ((STREAM), " -fgnu-linker"); \ - \ - if (profile_flag) \ - fprintf ((STREAM), " -p"); \ - \ - if (profile_block_flag) \ - fprintf ((STREAM), " -a"); \ - \ - if (TARGET_IEEE_FP) \ - fprintf ((STREAM), " -mieee-fp"); \ - \ - if (TARGET_HALF_PIC) \ - fprintf ((STREAM), " -mhalf-pic"); \ - \ - if (!TARGET_MOVE) \ - fprintf ((STREAM), " -mno-move"); \ - \ - if (TARGET_386) \ - fprintf ((STREAM), " -m386"); \ - \ - else if (TARGET_486) \ - fprintf ((STREAM), " -m486"); \ - \ - else \ - fprintf ((STREAM), " -munknown-machine"); \ - \ - fprintf ((STREAM), (TARGET_ELF) ? " -melf\"\n" : " -mrose\"\n"); \ - } \ - } \ -while (0) - -/* Tell collect that the object format is OSF/rose. */ -#define OBJECT_FORMAT_ROSE - -/* Tell collect where the appropriate binaries are. */ -#define REAL_NM_FILE_NAME "/usr/ccs/gcc/bfd-nm" -#define REAL_STRIP_FILE_NAME "/usr/ccs/bin/strip" - -/* Use atexit for static constructors/destructors, instead of defining - our own exit function. */ -#define HAVE_ATEXIT - -/* Define this macro meaning that gcc should find the library 'libgcc.a' - by hand, rather than passing the argument '-lgcc' to tell the linker - to do the search */ -#define LINK_LIBGCC_SPECIAL - -/* A C statement to output assembler commands which will identify the object - file as having been compile with GNU CC. We don't need or want this for - OSF1. GDB doesn't need it and kdb doesn't like it */ -#define ASM_IDENTIFY_GCC(FILE) - -/* Identify the front-end which produced this file. To keep symbol - space down, and not confuse kdb, only do this if the language is - not C. */ - -#define ASM_IDENTIFY_LANGUAGE(STREAM) \ -{ \ - if (strcmp (lang_identify (), "c") != 0) \ - output_lang_identify (STREAM); \ -} - -/* Generate calls to memcpy, etc., not bcopy, etc. */ -#define TARGET_MEM_FUNCTIONS - -/* Don't default to pcc-struct-return, because gcc is the only compiler, and - we want to retain compatibility with older gcc versions. */ -#define DEFAULT_PCC_STRUCT_RETURN 0 - -/* Map i386 registers to the numbers dwarf expects. Of course this is different - from what stabs expects. */ - -#define DWARF_DBX_REGISTER_NUMBER(n) \ -((n) == 0 ? 0 \ - : (n) == 1 ? 2 \ - : (n) == 2 ? 1 \ - : (n) == 3 ? 3 \ - : (n) == 4 ? 6 \ - : (n) == 5 ? 7 \ - : (n) == 6 ? 5 \ - : (n) == 7 ? 4 \ - : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \ - : (-1)) - -/* Now what stabs expects in the register. */ -#define STABS_DBX_REGISTER_NUMBER(n) \ -((n) == 0 ? 0 : \ - (n) == 1 ? 2 : \ - (n) == 2 ? 1 : \ - (n) == 3 ? 3 : \ - (n) == 4 ? 6 : \ - (n) == 5 ? 7 : \ - (n) == 6 ? 4 : \ - (n) == 7 ? 5 : \ - (n) + 4) - -#undef DBX_REGISTER_NUMBER -#define DBX_REGISTER_NUMBER(n) ((write_symbols == DWARF_DEBUG) \ - ? DWARF_DBX_REGISTER_NUMBER(n) \ - : STABS_DBX_REGISTER_NUMBER(n)) diff --git a/support/cpp/i386/perform.h b/support/cpp/i386/perform.h deleted file mode 100644 index 8d6d0b71..00000000 --- a/support/cpp/i386/perform.h +++ /dev/null @@ -1,98 +0,0 @@ -/* Definitions for AT&T assembler syntax for the Intel 80386. - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Defines to be able to build libgcc.a with GCC. */ - -/* It might seem that these are not important, since gcc 2 will never - call libgcc for these functions. But programs might be linked with - code compiled by gcc 1, and then these will be used. */ - -/* The arg names used to be a and b, but `a' appears inside strings - and that confuses non-ANSI cpp. */ - -#define perform_udivsi3(arg0,arg1) \ -{ \ - register int dx asm("dx"); \ - register int ax asm("ax"); \ - \ - dx = 0; \ - ax = arg0; \ - asm ("divl %3" : "=a" (ax), "=d" (dx) : "a" (ax), "g" (arg1), "d" (dx)); \ - return ax; \ -} - -#define perform_divsi3(arg0,arg1) \ -{ \ - register int dx asm("dx"); \ - register int ax asm("ax"); \ - register int cx asm("cx"); \ - \ - ax = arg0; \ - cx = arg1; \ - asm ("cltd\n\tidivl %3" : "=a" (ax), "=&d" (dx) : "a" (ax), "c" (cx)); \ - return ax; \ -} - -#define perform_umodsi3(arg0,arg1) \ -{ \ - register int dx asm("dx"); \ - register int ax asm("ax"); \ - \ - dx = 0; \ - ax = arg0; \ - asm ("divl %3" : "=a" (ax), "=d" (dx) : "a" (ax), "g" (arg1), "d" (dx)); \ - return dx; \ -} - -#define perform_modsi3(arg0,arg1) \ -{ \ - register int dx asm("dx"); \ - register int ax asm("ax"); \ - register int cx asm("cx"); \ - \ - ax = arg0; \ - cx = arg1; \ - asm ("cltd\n\tidivl %3" : "=a" (ax), "=&d" (dx) : "a" (ax), "c" (cx)); \ - return dx; \ -} - -#define perform_fixdfsi(arg0) \ -{ \ - auto unsigned short ostatus; \ - auto unsigned short nstatus; \ - auto int ret; \ - auto double tmp; \ - \ - &ostatus; /* guarantee these land in memory */ \ - &nstatus; \ - &ret; \ - &tmp; \ - \ - asm volatile ("fnstcw %0" : "=m" (ostatus)); \ - nstatus = ostatus | 0x0c00; \ - asm volatile ("fldcw %0" : /* no outputs */ : "m" (nstatus)); \ - tmp = arg0; \ - asm volatile ("fldl %0" : /* no outputs */ : "m" (tmp)); \ - asm volatile ("fistpl %0" : "=m" (ret)); \ - asm volatile ("fldcw %0" : /* no outputs */ : "m" (ostatus)); \ - \ - return ret; \ -} - diff --git a/support/cpp/i386/sco.h b/support/cpp/i386/sco.h deleted file mode 100644 index 37dc0326..00000000 --- a/support/cpp/i386/sco.h +++ /dev/null @@ -1,117 +0,0 @@ -/* Definitions for Intel 386 running SCO Unix System V. - Copyright (C) 1988, 1992, 1994, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Mostly it's like AT&T Unix System V. */ - -#include "i386/sysv3.h" - -/* By default, target has a 80387, uses IEEE compatible arithmetic, - and returns float values in the 387, ie, - (TARGET_80387 | TARGET_FLOAT_RETURNS_IN_80387) - - SCO's software emulation of a 387 fails to handle the `fucomp' - opcode. fucomp is only used when generating IEEE compliant code. - So don't make TARGET_IEEE_FP default for SCO. */ - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT 0201 - -/* Let's guess that the SCO software FPU emulator can't handle - 80-bit XFmode insns, so don't generate them. */ -#undef LONG_DOUBLE_TYPE_SIZE -#define LONG_DOUBLE_TYPE_SIZE 64 - -/* Use crt1.o as a startup file and crtn.o as a closing file. */ - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC \ - "%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}} crtbegin.o%s" - -#define ENDFILE_SPEC "crtend.o%s crtn.o%s" - -/* Library spec, including SCO international language support. */ - -#undef LIB_SPEC -#define LIB_SPEC \ - "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} %{scointl:libintl.a%s} -lc" - -/* Specify predefined symbols in preprocessor. */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dunix -Di386 -DM_UNIX -DM_I386 -DM_COFF -DM_WORDSWAP -Asystem(unix) -Asystem(svr3) -Acpu(i386) -Amachine(i386)" - -#undef CPP_SPEC -#define CPP_SPEC "%{scointl:-DM_INTERNAT}" - -/* This spec is used for telling cpp whether char is signed or not. */ - -#undef SIGNED_CHAR_SPEC -#if DEFAULT_SIGNED_CHAR -#define SIGNED_CHAR_SPEC \ - "%{funsigned-char:-D__CHAR_UNSIGNED__ -D_CHAR_UNSIGNED}" -#else -#define SIGNED_CHAR_SPEC \ - "%{!fsigned-char:-D__CHAR_UNSIGNED__ -D_CHAR_UNSIGNED}" -#endif - -/* Use atexit for static destructors, instead of defining - our own exit function. */ -#define HAVE_ATEXIT - -/* Specify the size_t type. */ -#define SIZE_TYPE "unsigned int" - -#if 0 /* Not yet certain whether this is needed. */ -/* If no 387, use the general regs to return floating values, - since this system does not emulate the 80387. */ - -#undef VALUE_REGNO -#define VALUE_REGNO(MODE) \ - ((TARGET_80387 - && ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode) - ? FIRST_FLOAT_REG : 0) - -#undef HARD_REGNO_MODE_OK -#define HARD_REGNO_MODE_OK(REGNO, MODE) \ - ((REGNO) < 2 ? 1 \ - : (REGNO) < 4 ? 1 \ - : FP_REGNO_P (REGNO) ? ((GET_MODE_CLASS (MODE) == MODE_FLOAT \ - || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \ - && TARGET_80387 \ - && GET_MODE_UNIT_SIZE (MODE) <= 8) \ - : (MODE) != QImode) -#endif - -/* caller has to pop the extra argument passed to functions that return - structures. */ - -#undef RETURN_POPS_ARGS -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \ - (TREE_CODE (FUNTYPE) == IDENTIFIER_NODE ? 0 \ - : (TARGET_RTD \ - && (TYPE_ARG_TYPES (FUNTYPE) == 0 \ - || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ - == void_type_node))) ? (SIZE) \ - : 0) -/* On other 386 systems, the last line looks like this: - : (aggregate_value_p (TREE_TYPE (FUNTYPE))) ? GET_MODE_SIZE (Pmode) : 0) */ - -/* Handle #pragma pack. */ -#define HANDLE_SYSV_PRAGMA diff --git a/support/cpp/i386/sco4.h b/support/cpp/i386/sco4.h deleted file mode 100644 index fc389b4d..00000000 --- a/support/cpp/i386/sco4.h +++ /dev/null @@ -1,86 +0,0 @@ -/* Definitions for Intel 386 running SCO Unix System V 3.2 Version 4. - Written by Chip Salzenberg. - Copyright (C) 1992, 1994 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Mostly it's like earlier SCO UNIX. */ - -#include "i386/sco.h" - -/* Use crt1.o as a startup file and crtn.o as a closing file. */ - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC \ - "%{scoxpg3:%{p:mcrt1X.o%s}%{!p:crt1X.o%s}} \ - %{!scoxpg3:\ - %{posix:%{p:mcrt1P.o%s}%{!p:crt1P.o%s}} \ - %{!posix:\ - %{ansi:%{p:mcrt1A.o%s}%{!p:crt1A.o%s}} \ - %{!ansi:%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}}}} \ - crtbegin.o%s" - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC \ - "crtend.o%s \ - %{scoxpg3:crtnX.o%s} \ - %{!scoxpg3:\ - %{posix:crtnP.o%s} \ - %{!posix:\ - %{ansi:crtnA.o%s} \ - %{!ansi:crtn.o%s}}}" - -/* Library spec. */ - -#undef LIB_SPEC -#define LIB_SPEC \ - "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} \ - %{scoxpg3:-lcX -lcP -lcA} \ - %{!scoxpg3:\ - %{posix:-lcP -lcA} \ - %{!posix:\ - %{ansi:-lcA} \ - %{!ansi:%{scointl:-lintl} -lc}}}" - -/* Macros, macros everywhere: - Specify predefined symbols in preprocessor. */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES \ - "-Asystem(unix) -Asystem(svr3) -Acpu(i386) -Amachine(i386)" - -#undef CPP_SPEC -#define CPP_SPEC \ - "-D_i386 -D_M_I386 -D_M_I86 -D_M_I86SM -D_M_SDATA -D_M_STEXT \ - -D_unix -D_M_UNIX -D_M_XENIX \ - -D_M_SYS5 -D_M_SYSV -D_M_SYS3 -D_M_SYSIII \ - -D_M_COFF -D_M_BITFIELDS -D_M_WORDSWAP \ - %{scoxpg3:-D_XOPEN_SOURCE -D_STRICT_NAMES} \ - %{!scoxpg3:%{posix:-D_POSIX_SOURCE -D_STRICT_NAMES}} \ - %{!scoxpg3:%{!posix:\ - %{ansi:-D_STRICT_NAMES}%{!ansi:\ - -Di386 -DM_I386 -DM_I86 -DM_I86SM -DM_SDATA -DM_STEXT \ - -Dunix -DM_UNIX -DM_XENIX \ - -DM_SYS5 -DM_SYSV -DM_SYS3 -DM_SYSIII \ - -DM_COFF -DM_BITFIELDS -DM_WORDSWAP \ - %{scointl:-D_M_INTERNAT -DM_INTERNAT} \ - %{traditional:-D_KR -D_SVID -D_NO_PROTOTYPE}}}}" - -/* The system headers are C++-aware. */ -#define NO_IMPLICIT_EXTERN_C diff --git a/support/cpp/i386/sco4dbx.h b/support/cpp/i386/sco4dbx.h deleted file mode 100644 index 0387c243..00000000 --- a/support/cpp/i386/sco4dbx.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Definitions for Intel 386 running SCO Unix System V 3.2 Version 4.s, - using dbx-in-coff encapsulation. - Copyright (C) 1992 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Mostly it's like earlier SCO UNIX. */ - -#include "i386/scodbx.h" - -/* Use crt1.o as a startup file and crtn.o as a closing file. */ - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC \ - "%{!r:%{!z:gcc.ifile%s}%{z:gccz.ifile%s}}\ - %{scoxpg3:%{p:mcrt1X.o%s}%{!p:crt1X.o%s}} \ - %{!scoxpg3:\ - %{posix:%{p:mcrt1P.o%s}%{!p:crt1P.o%s}} \ - %{!posix:\ - %{ansi:%{p:mcrt1A.o%s}%{!p:crt1A.o%s}} \ - %{!ansi:%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}}}}" - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC \ - "%{scoxpg3:crtnX.o%s} \ - %{!scoxpg3:\ - %{posix:crtnP.o%s} \ - %{!posix:\ - %{ansi:crtnA.o%s} \ - %{!ansi:crtn.o%s}}}" - -/* Library spec. */ - -#undef LIB_SPEC -#define LIB_SPEC \ - "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} \ - %{scoxpg3:-lcX -lcP -lcA} \ - %{!scoxpg3:\ - %{posix:-lcP -lcA} \ - %{!posix:\ - %{ansi:-lcA} \ - %{!ansi:%{scointl:-lintl} -lc}}}" - -/* Macros, macros everywhere: - Specify predefined symbols in preprocessor. */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Di386 -Dunix -Asystem(unix) -Asystem(svr3) -Acpu(i386) -Amachine(i386)" - -#undef CPP_SPEC -#define CPP_SPEC \ - "-D_M_I386 -D_M_I86 -D_M_I86SM -D_M_SDATA -D_M_STEXT \ - -D_M_UNIX -D_M_XENIX \ - -D_M_SYS5 -D_M_SYSV -D_M_SYS3 -D_M_SYSIII \ - -D_M_COFF -D_M_BITFIELDS -D_M_WORDSWAP \ - %{scoxpg3:-D_XOPEN_SOURCE -D_STRICT_NAMES} \ - %{!scoxpg3:%{posix:-D_POSIX_SOURCE -D_STRICT_NAMES}} \ - %{!scoxpg3:%{!posix:\ - %{ansi:-D_STRICT_NAMES}%{!ansi:\ - -DM_I386 -DM_I86 -DM_I86SM -DM_SDATA -DM_STEXT \ - -DM_UNIX -DM_XENIX \ - -DM_SYS5 -DM_SYSV -DM_SYS3 -DM_SYSIII \ - -DM_COFF -DM_BITFIELDS -DM_WORDSWAP \ - %{scointl:-D_M_INTERNAT -DM_INTERNAT} \ - %{traditional:-D_KR -D_SVID -D_NO_PROTOTYPE}}}}" diff --git a/support/cpp/i386/scodbx.h b/support/cpp/i386/scodbx.h deleted file mode 100644 index 1309735c..00000000 --- a/support/cpp/i386/scodbx.h +++ /dev/null @@ -1,92 +0,0 @@ -/* Definitions for Intel 386 running SCO Unix System V, - using dbx-in-coff encapsulation. - Copyright (C) 1992, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "i386/svr3dbx.h" - -/* Overridden defines for SCO systems from sco.h. */ - -/* By default, target has a 80387, uses IEEE compatible arithmetic, - and returns float values in the 387, ie, - (TARGET_80387 | TARGET_FLOAT_RETURNS_IN_80387) - - SCO's software emulation of a 387 fails to handle the `fucomp' - opcode. fucomp is only used when generating IEEE compliant code. - So don't make TARGET_IEEE_FP default for SCO. */ - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT 0201 - -/* Use crt1.o as a startup file and crtn.o as a closing file. */ - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC \ - "%{!r:%{!z:svr3.ifile%s}%{z:svr3z.ifile%s}}\ - %{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}" - -/* Library spec, including SCO international language support. */ - -#undef LIB_SPEC -#define LIB_SPEC \ - "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} %{scointl:libintl.a%s} -lc" - -/* Specify predefined symbols in preprocessor. */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dunix -Di386 -DM_UNIX -DM_I386 -DM_COFF -DM_WORDSWAP -Asystem(unix) -Asystem(svr3) -Acpu(i386) -Amachine(i386)" - -#undef CPP_SPEC -#define CPP_SPEC "%{scointl:-DM_INTERNAT}" - -/* This spec is used for telling cpp whether char is signed or not. */ - -#undef SIGNED_CHAR_SPEC -#if DEFAULT_SIGNED_CHAR -#define SIGNED_CHAR_SPEC \ - "%{funsigned-char:-D__CHAR_UNSIGNED__ -D_CHAR_UNSIGNED}" -#else -#define SIGNED_CHAR_SPEC \ - "%{!fsigned-char:-D__CHAR_UNSIGNED__ -D_CHAR_UNSIGNED}" -#endif - -/* Use atexit for static destructors, instead of defining - our own exit function. */ -#define HAVE_ATEXIT - -/* caller has to pop the extra argument passed to functions that return - structures. */ - -#undef RETURN_POPS_ARGS -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \ - (TREE_CODE (FUNTYPE) == IDENTIFIER_NODE ? 0 \ - : (TARGET_RTD \ - && (TYPE_ARG_TYPES (FUNTYPE) == 0 \ - || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ - == void_type_node))) ? (SIZE) \ - : 0) -/* On other 386 systems, the last line looks like this: - : (aggregate_value_p (TREE_TYPE (FUNTYPE))) ? GET_MODE_SIZE (Pmode) : 0) */ - -/* Use periods rather than dollar signs in special g++ assembler names. */ - -#define NO_DOLLAR_IN_LABEL - -/* Handle #pragma pack. */ -#define HANDLE_SYSV_PRAGMA diff --git a/support/cpp/i386/seq-gas.h b/support/cpp/i386/seq-gas.h deleted file mode 100644 index 2ee07192..00000000 --- a/support/cpp/i386/seq-gas.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Definitions for Sequent Intel 386 using GAS. - Copyright (C) 1992 Free Software Foundation, Inc. - -/* Mostly it's like a Sequent 386 without GAS. */ - -#include "i386/sequent.h" - -/* A C statement or statements which output an assembler instruction - opcode to the stdio stream STREAM. The macro-operand PTR is a - variable of type `char *' which points to the opcode name in its - "internal" form--the form that is written in the machine description. - - GAS version 1.38.1 doesn't understand the `repz' opcode mnemonic. - So use `repe' instead. */ - -#undef ASM_OUTPUT_OPCODE -#define ASM_OUTPUT_OPCODE(STREAM, PTR) \ -{ \ - if ((PTR)[0] == 'r' \ - && (PTR)[1] == 'e' \ - && (PTR)[2] == 'p') \ - { \ - if ((PTR)[3] == 'z') \ - { \ - fprintf (STREAM, "repe"); \ - (PTR) += 4; \ - } \ - else if ((PTR)[3] == 'n' && (PTR)[4] == 'z') \ - { \ - fprintf (STREAM, "repne"); \ - (PTR) += 5; \ - } \ - } \ -} - -/* Define macro used to output shift-double opcodes when the shift - count is in %cl. Some assemblers require %cl as an argument; - some don't. - - GAS requires the %cl argument, so override i386/unix.h. */ - -#undef AS3_SHIFT_DOUBLE -#define AS3_SHIFT_DOUBLE(a,b,c,d) AS3 (a,b,c,d) - -/* Print opcodes the way that GAS expects them. */ -#define GAS_MNEMONICS 1 diff --git a/support/cpp/i386/seq-sysv3.h b/support/cpp/i386/seq-sysv3.h deleted file mode 100644 index e3182ee1..00000000 --- a/support/cpp/i386/seq-sysv3.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Sequent DYNIX/ptx 1.x (SVr3) */ - -#include "i386/sysv3.h" - -/* Sequent Symmetry SVr3 doesn't have crtn.o; crt1.o doesn't work - but crt0.o does. */ - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC \ -"%{pg:gcrt0.o%s}\ - %{!pg:%{posix:%{p:mcrtp0.o%s}%{!p:crtp0.o%s}}\ - %{!posix:%{p:mcrt0.o%s}%{!p:crt0.o%s}}} crtbegin.o%s\ - %{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp}" - -#undef LIB_SPEC -#define LIB_SPEC \ -"%{posix:-lcposix}\ - %{shlib:-lc_s}\ - %{fshared-data:-lpps -lseq} -lc crtend.o%s" - -#undef CPP_SPEC -#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} -D_SEQUENT_=1" - -/* Although the .init section is used, it is not automatically invoked. - This because the _start() function in /lib/crt0.o never calls anything - from the .init section */ -#define INVOKE__main - -/* Assembler pseudo-op for initialized shared variables (.shdata). */ -#undef SHARED_SECTION_ASM_OP -#define SHARED_SECTION_ASM_OP ".section .shdata, \"ws\"" - -/* Assembler pseudo-op for uninitialized shared global variables (.shbss). */ -#undef ASM_OUTPUT_SHARED_COMMON -#define ASM_OUTPUT_SHARED_COMMON(FILE, NAME, SIZE, ROUNDED) \ -( fputs(".comm ", (FILE)), \ - assemble_name((FILE), (NAME)), \ - fprintf((FILE), ",%u,-3\n", (SIZE))) - -/* Assembler pseudo-op for uninitialized shared local variables (.shbss). */ -#undef SHARED_BSS_SECTION_ASM_OP -#define SHARED_BSS_SECTION_ASM_OP ".section .shbss, \"bs\"" -#undef BSS_SECTION_FUNCTION -#define BSS_SECTION_FUNCTION \ -void \ -bss_section () \ -{ \ - if (in_section != in_bss) \ - { \ - if (flag_shared_data) \ - fprintf (asm_out_file, "%s\n", SHARED_BSS_SECTION_ASM_OP); \ - else \ - fprintf (asm_out_file, "%s\n", BSS_SECTION_ASM_OP); \ - in_section = in_bss; \ - } \ -} diff --git a/support/cpp/i386/seq2-sysv3.h b/support/cpp/i386/seq2-sysv3.h deleted file mode 100644 index 763c5f0a..00000000 --- a/support/cpp/i386/seq2-sysv3.h +++ /dev/null @@ -1,8 +0,0 @@ -/* Sequent DYNIX/ptx 2.x (SVr3) */ - -#include "i386/seq-sysv3.h" - -/* Use atexit for static destructors, instead of defining - our own exit function. */ -#define HAVE_ATEXIT - diff --git a/support/cpp/i386/sequent.h b/support/cpp/i386/sequent.h deleted file mode 100644 index 4d76c389..00000000 --- a/support/cpp/i386/sequent.h +++ /dev/null @@ -1,152 +0,0 @@ -/* Definitions for Sequent Intel 386. - Copyright (C) 1988, 1994 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "i386/i386.h" - -/* Use the BSD assembler syntax. */ - -#include "i386/bsd.h" - -/* By default, don't use IEEE compatible arithmetic comparisons - because the assembler can't handle the fucom insn. - Return float values in the 387. - (TARGET_80387 | TARGET_FLOAT_RETURNS_IN_80387) */ - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT 0201 - -/* Specify predefined symbols in preprocessor. */ - -#define CPP_PREDEFINES "-Dunix -Di386 -Dsequent -Asystem(unix) -Acpu(i386) -Amachine(i386)" - -/* Pass -Z and -ZO options to the linker. */ - -#define LINK_SPEC "%{Z*}" - -#if 0 /* Dynix 3.1 is said to accept -L. */ -/* Dynix V3.0.12 doesn't accept -L at all. */ - -#define LINK_LIBGCC_SPECIAL -#endif - -/* Link with libg.a when debugging, for dbx's sake. */ - -#define LIB_SPEC "%{g:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} " - -/* We don't want to output SDB debugging information. */ - -#undef SDB_DEBUGGING_INFO - -/* We want to output DBX debugging information. */ - -#define DBX_DEBUGGING_INFO - -/* Sequent Symmetry has size_t defined as int in /usr/include/sys/types.h */ -#define SIZE_TYPE "int" - -/* gcc order is ax, dx, cx, bx, si, di, bp, sp, st, st. - * dbx order is ax, dx, cx, st(0), st(1), bx, si, di, st(2), st(3), - * st(4), st(5), st(6), st(7), sp, bp */ - -/* ??? The right thing would be to change the ordering of the - registers to correspond to the conventions of this system, - and get rid of DBX_REGISTER_NUMBER. */ - -#undef DBX_REGISTER_NUMBER -#define DBX_REGISTER_NUMBER(n) \ -((n) < 3 ? (n) : (n) < 6 ? (n) + 2 \ - : (n) == 6 ? 15 : (n) == 7 ? 14 : 3) - -/* malcolmp@hydra.maths.unsw.EDU.AU says these two definitions - fix trouble in dbx. */ -#undef DBX_OUTPUT_LBRAC -#define DBX_OUTPUT_LBRAC(file,name) \ - fprintf (asmfile, "%s %d,0,%d,", ASM_STABN_OP, N_LBRAC, depth); \ - assemble_name (asmfile, buf); \ - fprintf (asmfile, "\n"); - -#undef DBX_OUTPUT_RBRAC -#define DBX_OUTPUT_RBRAC(file,name) \ - fprintf (asmfile, "%s %d,0,%d,", ASM_STABN_OP, N_RBRAC, depth); \ - assemble_name (asmfile, buf); \ - fprintf (asmfile, "\n"); - -/* Prevent anything from being allocated in the register pair cx/bx, - since that would confuse GDB. */ - -#undef HARD_REGNO_MODE_OK -#define HARD_REGNO_MODE_OK(REGNO, MODE) \ - (((REGNO) < 2 ? 1 \ - : (REGNO) < 4 ? 1 \ - : FP_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_FLOAT \ - || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \ - : (MODE) != QImode) \ - && ! (REGNO == 2 && GET_MODE_UNIT_SIZE (MODE) > 4)) - -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. */ - -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) \ - fprintf (FILE, "\tmovl $.LP%d,%%eax\n\tcall mcount\n", (LABELNO)); - -/* Assembler pseudo-op for shared data segment. */ -#define SHARED_SECTION_ASM_OP ".shdata" - -/* A C statement or statements which output an assembler instruction - opcode to the stdio stream STREAM. The macro-operand PTR is a - variable of type `char *' which points to the opcode name in its - "internal" form--the form that is written in the machine description. - - The Sequent assembler (identified as "Balance 8000 Assembler - 07/17/85 3.90" by "as -v") does not understand the `movs[bwl]' string - move mnemonics - it uses `smov[bwl]' instead. Change "movs" into - "smov", carefully avoiding the sign-extend opcodes. */ - -#define ASM_OUTPUT_OPCODE(STREAM, PTR) \ -{ \ - if ((PTR)[0] == 'm' \ - && (PTR)[1] == 'o' \ - && (PTR)[2] == 'v' \ - && (PTR)[3] == 's' \ - && ((PTR)[4] == 'b' || (PTR)[4] == 'w' || (PTR)[4] == 'l') \ - && ((PTR)[5] == ' ' || (PTR)[5] == '\t'|| (PTR)[5] == '\0')) \ - { \ - fprintf (STREAM, "smov"); \ - (PTR) += 4; \ - } \ -} - -/* 10-Aug-92 pes Local labels are prefixed with ".L" */ -#undef LPREFIX -#define LPREFIX ".L" - -#undef ASM_GENERATE_INTERNAL_LABEL -#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER)\ - sprintf ((BUF), "*.%s%d", (PREFIX), (NUMBER)) - -#undef ASM_OUTPUT_INTERNAL_LABEL -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)\ - fprintf (FILE, ".%s%d:\n", PREFIX, NUM) - -/* The native compiler passes the address of the returned structure in eax. */ -#undef STRUCT_VALUE -#undef STRUCT_VALUE_INCOMING -#define STRUCT_VALUE_REGNUM 0 diff --git a/support/cpp/i386/sol2-c1.asm b/support/cpp/i386/sol2-c1.asm deleted file mode 100644 index 72fdfb87..00000000 --- a/support/cpp/i386/sol2-c1.asm +++ /dev/null @@ -1,156 +0,0 @@ -! crt1.s for Solaris 2, x86 - -! Copyright (C) 1993 Free Software Foundation, Inc. -! Written By Fred Fish, Nov 1992 -! -! This file is free software; you can redistribute it and/or modify it -! under the terms of the GNU General Public License as published by the -! Free Software Foundation; either version 2, or (at your option) any -! later version. -! -! In addition to the permissions in the GNU General Public License, the -! Free Software Foundation gives you unlimited permission to link the -! compiled version of this file with other programs, and to distribute -! those programs without any restriction coming from the use of this -! file. (The General Public License restrictions do apply in other -! respects; for example, they cover modification of the file, and -! distribution when not linked into another program.) -! -! This file is distributed in the hope that it will be useful, but -! WITHOUT ANY WARRANTY; without even the implied warranty of -! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -! General Public License for more details. -! -! You should have received a copy of the GNU General Public License -! along with this program; see the file COPYING. If not, write to -! the Free Software Foundation, 59 Temple Place - Suite 330, -! Boston, MA 02111-1307, USA. -! -! As a special exception, if you link this library with files -! compiled with GCC to produce an executable, this does not cause -! the resulting executable to be covered by the GNU General Public License. -! This exception does not however invalidate any other reasons why -! the executable file might be covered by the GNU General Public License. -! - -! This file takes control of the process from the kernel, as specified -! in section 3 of the System V Application Binary Interface, Intel386 -! Processor Supplement. It has been constructed from information obtained -! from the ABI, information obtained from single stepping existing -! Solaris executables through their startup code with gdb, and from -! information obtained by single stepping executables on other i386 SVR4 -! implementations. This file is the first thing linked into any executable. - - .file "crt1.s" - .ident "GNU C crt1.s" - .weak _cleanup - .weak _DYNAMIC - .text - -! Start creating the initial frame by pushing a NULL value for the return -! address of the initial frame, and mark the end of the stack frame chain -! (the innermost stack frame) with a NULL value, per page 3-32 of the ABI. -! Initialize the first stack frame pointer in %ebp (the contents of which -! are unspecified at process initialization). - - .globl _start -_start: - pushl $0x0 - pushl $0x0 - movl %esp,%ebp - -! As specified per page 3-32 of the ABI, %edx contains a function -! pointer that should be registered with atexit(), for proper -! shared object termination. Just push it onto the stack for now -! to preserve it. We want to register _cleanup() first. - - pushl %edx - -! Check to see if there is an _cleanup() function linked in, and if -! so, register it with atexit() as the last thing to be run by -! atexit(). - - movl $_cleanup,%eax - testl %eax,%eax - je .L1 - pushl $_cleanup - call atexit - addl $0x4,%esp -.L1: - -! Now check to see if we have an _DYNAMIC table, and if so then -! we need to register the function pointer previously in %edx, but -! now conveniently saved on the stack as the argument to pass to -! atexit(). - - movl $_DYNAMIC,%eax - testl %eax,%eax - je .L2 - call atexit -.L2: - -! Register _fini() with atexit(). We will take care of calling _init() -! directly. - - pushl $_fini - call atexit - -! Compute the address of the environment vector on the stack and load -! it into the global variable _environ. Currently argc is at 8 off -! the frame pointer. Fetch the argument count into %eax, scale by the -! size of each arg (4 bytes) and compute the address of the environment -! vector which is 16 bytes (the two zero words we pushed, plus argc, -! plus the null word terminating the arg vector) further up the stack, -! off the frame pointer (whew!). - - movl 8(%ebp),%eax - leal 16(%ebp,%eax,4),%edx - movl %edx,_environ - -! Push the environment vector pointer, the argument vector pointer, -! and the argument count on to the stack to set up the arguments -! for _init(), _fpstart(), and main(). Note that the environment -! vector pointer and the arg count were previously loaded into -! %edx and %eax respectively. The only new value we need to compute -! is the argument vector pointer, which is at a fixed address off -! the initial frame pointer. - - pushl %edx - leal 12(%ebp),%edx - pushl %edx - pushl %eax - -! Call _init(argc, argv, environ), _fpstart(argc, argv, environ), and -! main(argc, argv, environ). - - call _init - call __fpstart - call main - -! Pop the argc, argv, and environ arguments off the stack, push the -! value returned from main(), and call exit(). - - addl $12,%esp - pushl %eax - call exit - -! An inline equivalent of _exit, as specified in Figure 3-26 of the ABI. - - pushl $0x0 - movl $0x1,%eax - lcall $7,$0 - -! If all else fails, just try a halt! - - hlt - .type _start,@function - .size _start,.-_start - -! A dummy profiling support routine for non-profiling executables, -! in case we link in some objects that have been compiled for profiling. - - .globl _mcount -_mcount: - ret - .type _mcount,@function - .size _mcount,.-_mcount diff --git a/support/cpp/i386/sol2-ci.asm b/support/cpp/i386/sol2-ci.asm deleted file mode 100644 index 439c709b..00000000 --- a/support/cpp/i386/sol2-ci.asm +++ /dev/null @@ -1,51 +0,0 @@ -! crti.s for Solaris 2, x86. - -! Copyright (C) 1993 Free Software Foundation, Inc. -! Written By Fred Fish, Nov 1992 -! -! This file is free software; you can redistribute it and/or modify it -! under the terms of the GNU General Public License as published by the -! Free Software Foundation; either version 2, or (at your option) any -! later version. -! -! In addition to the permissions in the GNU General Public License, the -! Free Software Foundation gives you unlimited permission to link the -! compiled version of this file with other programs, and to distribute -! those programs without any restriction coming from the use of this -! file. (The General Public License restrictions do apply in other -! respects; for example, they cover modification of the file, and -! distribution when not linked into another program.) -! -! This file is distributed in the hope that it will be useful, but -! WITHOUT ANY WARRANTY; without even the implied warranty of -! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -! General Public License for more details. -! -! You should have received a copy of the GNU General Public License -! along with this program; see the file COPYING. If not, write to -! the Free Software Foundation, 59 Temple Place - Suite 330, -! Boston, MA 02111-1307, USA. -! -! As a special exception, if you link this library with files -! compiled with GCC to produce an executable, this does not cause -! the resulting executable to be covered by the GNU General Public License. -! This exception does not however invalidate any other reasons why -! the executable file might be covered by the GNU General Public License. -! - -! This file just supplies labeled starting points for the .init and .fini -! sections. It is linked in before the values-Xx.o files and also before -! crtbegin.o. - - .file "crti.s" - .ident "GNU C crti.s" - - .section .init - .globl _init - .type _init,@function -_init: - - .section .fini - .globl _fini - .type _fini,@function -_fini: diff --git a/support/cpp/i386/sol2-cn.asm b/support/cpp/i386/sol2-cn.asm deleted file mode 100644 index 3f3bad93..00000000 --- a/support/cpp/i386/sol2-cn.asm +++ /dev/null @@ -1,46 +0,0 @@ -! crtn.s for Solaris 2, x86. - -! Copyright (C) 1993 Free Software Foundation, Inc. -! Written By Fred Fish, Nov 1992 -! -! This file is free software; you can redistribute it and/or modify it -! under the terms of the GNU General Public License as published by the -! Free Software Foundation; either version 2, or (at your option) any -! later version. -! -! In addition to the permissions in the GNU General Public License, the -! Free Software Foundation gives you unlimited permission to link the -! compiled version of this file with other programs, and to distribute -! those programs without any restriction coming from the use of this -! file. (The General Public License restrictions do apply in other -! respects; for example, they cover modification of the file, and -! distribution when not linked into another program.) -! -! This file is distributed in the hope that it will be useful, but -! WITHOUT ANY WARRANTY; without even the implied warranty of -! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -! General Public License for more details. -! -! You should have received a copy of the GNU General Public License -! along with this program; see the file COPYING. If not, write to -! the Free Software Foundation, 59 Temple Place - Suite 330, -! Boston, MA 02111-1307, USA. -! -! As a special exception, if you link this library with files -! compiled with GCC to produce an executable, this does not cause -! the resulting executable to be covered by the GNU General Public License. -! This exception does not however invalidate any other reasons why -! the executable file might be covered by the GNU General Public License. -! - -! This file just supplies returns for the .init and .fini sections. It is -! linked in after all other files. - - .file "crtn.o" - .ident "GNU C crtn.o" - - .section .init - ret $0x0 - - .section .fini - ret $0x0 diff --git a/support/cpp/i386/sol2.h b/support/cpp/i386/sol2.h deleted file mode 100644 index cc5ebca7..00000000 --- a/support/cpp/i386/sol2.h +++ /dev/null @@ -1,91 +0,0 @@ -/* Target definitions for GNU compiler for Intel 80386 running Solaris 2 - Copyright (C) 1993, 1995 Free Software Foundation, Inc. - - Written by Fred Fish (fnf@cygnus.com). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "i386/sysv4.h" - -/* The Solaris 2.0 x86 linker botches alignment of code sections. - It tries to align to a 16 byte boundary by padding with 0x00000090 - ints, rather than 0x90 bytes (nop). This generates trash in the - ".init" section since the contribution from crtbegin.o is only 7 - bytes. The linker pads it to 16 bytes with a single 0x90 byte, and - two 0x00000090 ints, which generates a segmentation violation when - executed. This macro forces the assembler to do the padding, since - it knows what it is doing. */ - -#define FORCE_INIT_SECTION_ALIGN do { asm (ALIGN_ASM_OP ## " 16"); } while (0) -#define FORCE_FINI_SECTION_ALIGN FORCE_INIT_SECTION_ALIGN - -/* Add "sun" to the list of symbols defined for SVR4. */ -#undef CPP_PREDEFINES -#define CPP_PREDEFINES \ - "-Di386 -Dunix -D__svr4__ -D__SVR4 -Dsun \ - -Asystem(unix) -Asystem(svr4) -Acpu(i386) -Amachine(i386)" - -#undef CPP_SPEC -#define CPP_SPEC "\ - %{compat-bsd:-iwithprefixbefore ucbinclude -I/usr/ucbinclude}" - -#undef LIB_SPEC -#define LIB_SPEC \ - "%{compat-bsd:-lucb -lsocket -lnsl -lelf -laio} %{!shared:%{!symbolic:-lc}}" - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC "crtend.o%s %{pg:crtn.o%s}%{!pg:crtn.o%s}" - -/* This should be the same as in svr4.h, except with -R added. */ -#undef LINK_SPEC -#define LINK_SPEC \ - "%{h*} %{V} %{v:%{!V:-V}} \ - %{b} %{Wl,*:%*} \ - %{static:-dn -Bstatic} \ - %{shared:-G -dy -z text} \ - %{symbolic:-Bsymbolic -G -dy -z text} \ - %{G:-G} \ - %{YP,*} \ - %{R*} \ - %{compat-bsd: \ - %{!YP,*:%{p:-Y P,/usr/ucblib:/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \ - %{!p:-Y P,/usr/ucblib:/usr/ccs/lib:/usr/lib}} \ - -R /usr/ucblib} \ - %{!compat-bsd: \ - %{!YP,*:%{p:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \ - %{!p:-Y P,/usr/ccs/lib:/usr/lib}}} \ - %{Qy:} %{!Qn:-Qy}" - -/* This defines which switch letters take arguments. - It is as in svr4.h but with -R added. */ - -#undef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) \ - ( (CHAR) == 'D' \ - || (CHAR) == 'U' \ - || (CHAR) == 'o' \ - || (CHAR) == 'e' \ - || (CHAR) == 'u' \ - || (CHAR) == 'I' \ - || (CHAR) == 'm' \ - || (CHAR) == 'L' \ - || (CHAR) == 'R' \ - || (CHAR) == 'A' \ - || (CHAR) == 'h' \ - || (CHAR) == 'z') - diff --git a/support/cpp/i386/sun.h b/support/cpp/i386/sun.h deleted file mode 100644 index ecc0e829..00000000 --- a/support/cpp/i386/sun.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Definitions for Intel 386 running SunOS 4.0. - Copyright (C) 1988, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#include "i386/i386.h" - -/* Use the Sun assembler syntax. */ - -#include "i386/sun386.h" - -/* Use crt0.o as a startup file. */ - -#define STARTFILE_SPEC \ - "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}" - -#define LIB_SPEC "%{g:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} \ -%{g:-lg} %{sun386:}" -/* That last item is just to prevent a spurious error. */ - -#undef LINK_SPEC -#define LINK_SPEC \ - "%{!nostdlib:%{!r*:%{!e*:-e _start}}} -dc -dp %{static:-Bstatic}" - -/* Extra switches to give the assembler. */ - -#define ASM_SPEC "%{R} -i386 %{keep-local-as-symbols:-L}" - -/* Specify predefined symbols in preprocessor. */ - -#define CPP_PREDEFINES "-Dunix -Di386 -Dsun386 -Dsun -Asystem(unix) -Asystem(bsd) -Acpu(i386) -Amachine(i386)" - -/* Allow #sccs in preprocessor. */ - -#define SCCS_DIRECTIVE - -/* Output #ident as a .ident. */ - -#define ASM_OUTPUT_IDENT(FILE, NAME) fprintf (FILE, "\t.ident \"%s\"\n", NAME); - -/* We don't want to output SDB debugging information. */ - -#undef SDB_DEBUGGING_INFO - -/* We want to output DBX debugging information. */ - -#define DBX_DEBUGGING_INFO - -/* Implicit library calls should use memcpy, not bcopy, etc. */ - -#define TARGET_MEM_FUNCTIONS - -/* Force structure alignment to the type used for a bitfield. */ - -#define PCC_BITFIELD_TYPE_MATTERS 1 - -/* This is partly guess. */ - -#undef DBX_REGISTER_NUMBER -#define DBX_REGISTER_NUMBER(n) \ - ((n) == 0 ? 11 : (n) == 1 ? 9 : (n) == 2 ? 10 : (n) == 3 ? 8 \ - : (n) == 4 ? 5 : (n) == 5 ? 4 : (n) == 6 ? 6 : (n)) - -/* Every debugger symbol must be in the text section. - Otherwise the assembler or the linker screws up. */ - -#define DEBUG_SYMS_TEXT diff --git a/support/cpp/i386/sun386.h b/support/cpp/i386/sun386.h deleted file mode 100644 index 6e268078..00000000 --- a/support/cpp/i386/sun386.h +++ /dev/null @@ -1,143 +0,0 @@ -/* Definitions for Sun assembler syntax for the Intel 80386. - Copyright (C) 1988 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Include common aspects of all 386 Unix assemblers. */ -#include "i386/unix.h" - -#define TARGET_VERSION fprintf (stderr, " (80386, Sun syntax)"); - -/* Define the syntax of instructions and addresses. */ - -/* Prefix for internally generated assembler labels. */ -#define LPREFIX ".L" - -/* Define the syntax of pseudo-ops, labels and comments. */ - -/* Assembler pseudos to introduce constants of various size. */ - -#define ASM_BYTE_OP "\t.byte" -#define ASM_SHORT "\t.value" -#define ASM_LONG "\t.long" -#define ASM_DOUBLE "\t.double" - -/* How to output an ASCII string constant. */ - -#define ASM_OUTPUT_ASCII(FILE, p, size) \ -do \ -{ int i = 0; \ - while (i < (size)) \ - { if (i%10 == 0) { if (i!=0) fprintf ((FILE), "\n"); \ - fprintf ((FILE), "%s ", ASM_BYTE_OP); } \ - else fprintf ((FILE), ","); \ - fprintf ((FILE), "0x%x", ((p)[i++] & 0377)) ;} \ - fprintf ((FILE), "\n"); \ -} while (0) - -/* Output at beginning of assembler file. */ -/* The .file command should always begin the output. */ - -#undef ASM_FILE_START -#define ASM_FILE_START(FILE) \ - do { \ - extern char *version_string, *language_string; \ - { \ - int len = strlen (dump_base_name); \ - char *na = dump_base_name + len; \ - char shorter[15]; \ - /* NA gets DUMP_BASE_NAME sans directory names. */\ - while (na > dump_base_name) \ - { \ - if (na[-1] == '/') \ - break; \ - na--; \ - } \ - strncpy (shorter, na, 14); \ - shorter[14] = 0; \ - fprintf (FILE, "\t.file\t"); \ - output_quoted_string (FILE, shorter); \ - fprintf (FILE, "\n"); \ - } \ - fprintf (FILE, "\t.version\t\"%s %s\"\n", \ - language_string, version_string); \ - if (optimize) ASM_FILE_START_1 (FILE); \ - } while (0) - -#define ASM_FILE_START_1(FILE) fprintf (FILE, "\t.optim\n") - -/* This is how to output an assembler line - that says to advance the location counter - to a multiple of 2**LOG bytes. */ - -#define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG)) - -/* This is how to output an assembler line - that says to advance the location counter by SIZE bytes. */ - -#define ASM_OUTPUT_SKIP(FILE,SIZE) \ - fprintf ((FILE), "\t.set\t.,.+%u\n", (SIZE)) - -/* Output before read-only data. */ - -#undef TEXT_SECTION_ASM_OP -#define TEXT_SECTION_ASM_OP ".text" - -/* Output before writable data. */ - -#undef DATA_SECTION_ASM_OP -#define DATA_SECTION_ASM_OP ".data" - -/* Define the syntax of labels and symbol definitions/declarations. */ - -/* This says how to output an assembler line - to define a global common symbol. */ - -#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ -( fputs (".comm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%u\n", (ROUNDED))) - -/* This says how to output an assembler line - to define a local common symbol. */ - -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ -( fputs (".lcomm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%u\n", (ROUNDED))) - -/* This is how to store into the string BUF - the symbol_ref name of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. */ - -#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ - sprintf ((BUF), "*.%s%d", (PREFIX), (NUMBER)) - -/* This is how to output a reference to a user-level label named NAME. */ - -#define ASM_OUTPUT_LABELREF(FILE,NAME) \ - fprintf (FILE, "%s", NAME) - -/* This is how to output an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. */ - -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - fprintf (FILE, ".%s%d:\n", PREFIX, NUM) diff --git a/support/cpp/i386/svr3.ifile b/support/cpp/i386/svr3.ifile deleted file mode 100644 index f0bb3a0f..00000000 --- a/support/cpp/i386/svr3.ifile +++ /dev/null @@ -1,45 +0,0 @@ -/* - * svr3.ifile - for collectless G++ on i386 System V. - * Leaves memory configured at address 0. - * - * Install this file as $prefix/gcc-lib/TARGET/VERSION/gcc.ifile - * - * BLOCK to an offset that leaves room for many headers ( the value - * here allows for a file header, an outheader, and up to 11 section - * headers on most systems. - * BIND to an address that includes page 0 in mapped memory. The value - * used for BLOCK should be or'd into this value. Here I'm setting BLOCK - * to 0x200 and BIND to ( value_used_for(BLOCK) ) - * If you are using shared libraries, watch that you don't overlap the - * address ranges assigned for shared libs. - * - * GROUP BIND to a location in the next segment. Here, the only value - * that you should change (I think) is that within NEXT, which I've set - * to my hardware segment size. You can always use a larger size, but not - * a smaller one. - */ -SECTIONS -{ - .text BIND(0x000200) BLOCK (0x200) : - { - /* plenty for room for headers */ - *(.init) - *(.text) - vfork = fork; /* I got tired of editing peoples sloppy code */ - *(.fini) - } - GROUP BIND( NEXT(0x400000) + (ADDR(.text) + (SIZEOF(.text)) % 0x1000)): - { - .data : { - __CTOR_LIST__ = . ; - . += 4 ; /* leading NULL */ - *(.ctor) - . += 4 ; /* trailing NULL */ - __DTOR_LIST__ = . ; - . += 4 ; /* leading NULL */ - *(.dtor) - . += 4 ; /* trailing NULL */ - } - .bss : { } - } -} diff --git a/support/cpp/i386/svr3dbx.h b/support/cpp/i386/svr3dbx.h deleted file mode 100644 index d3348d55..00000000 --- a/support/cpp/i386/svr3dbx.h +++ /dev/null @@ -1,97 +0,0 @@ -/* Definitions for Intel 386 running system V, using dbx-in-coff encapsulation. - Copyright (C) 1992, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "i386/svr3gas.h" - -/* We do not want to output SDB debugging information. */ - -#undef SDB_DEBUGGING_INFO - -/* We want to output DBX debugging information. */ - -#define DBX_DEBUGGING_INFO - -/* Compensate for botch in dbxout_init/dbxout_source_file which - unconditionally drops the first character from ltext_label_name */ - -#undef ASM_GENERATE_INTERNAL_LABEL -#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ - sprintf ((BUF), "*.%s%d", (PREFIX), (NUMBER)) - -/* With the current gas, .align N aligns to an N-byte boundary. - This is done to be compatible with the system assembler. - You must specify -DOTHER_ALIGN when building gas-1.38.1. */ - -#undef ASM_OUTPUT_ALIGN -#define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG)) - -/* Align labels, etc. at 4-byte boundaries. - For the 486, align to 16-byte boundary for sake of cache. */ - -#undef ASM_OUTPUT_ALIGN_CODE -#define ASM_OUTPUT_ALIGN_CODE(FILE) \ - fprintf ((FILE), "\t.align %d,0x90\n", \ - 1 << i386_align_jumps) - -/* Align start of loop at 4-byte boundary. */ - -#undef ASM_OUTPUT_LOOP_ALIGN -#define ASM_OUTPUT_LOOP_ALIGN(FILE) \ - fprintf ((FILE), "\t.align %d,0x90\n", 1 << i386_align_loops); - - -/* Additional overrides needed for dbx-in-coff gas, mostly taken from pbb.h */ - -/* Although the gas we use can create .ctor and .dtor sections from N_SETT - stabs, it does not support section directives, so we need to have the loader - define the lists. - */ -#define CTOR_LISTS_DEFINED_EXTERNALLY - -/* similar to default, but allows for the table defined by ld with svr3.ifile. - nptrs is always 0. So we need to instead check that __DTOR_LIST__[1] != 0. - The old check is left in so that the same macro can be used if and when - a future version of gas does support section directives. */ - -#define DO_GLOBAL_DTORS_BODY {int nptrs = *(int *)__DTOR_LIST__; int i; \ - if (nptrs == -1 || (__DTOR_LIST__[0] == 0 && __DTOR_LIST__[1] != 0)) \ - for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++); \ - for (i = nptrs; i >= 1; i--) \ - __DTOR_LIST__[i] (); } - -/* Use crt1.o as a startup file and crtn.o as a closing file. */ -/* - * The loader directive file svr3.ifile defines how to merge the constructor - * sections into the data section. Also, since gas only puts out those - * sections in response to N_SETT stabs, and does not (yet) have a - * ".sections" directive, svr3.ifile also defines the list symbols - * __DTOR_LIST__ and __CTOR_LIST__. - */ -#undef STARTFILE_SPEC -#define STARTFILE_SPEC \ - "%{!r:%{!z:svr3.ifile%s}%{z:svr3z.ifile%s}}\ - %{pg:gcrt1.o%s}%{!pg:%{posix:%{p:mcrtp1.o%s}%{!p:crtp1.o%s}}%{!posix:%{p:mcrt1.o%s}%{!p:crt1.o%s}}} \ - %{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp}" - -#define ENDFILE_SPEC "crtn.o%s" - -#undef LIB_SPEC -#define LIB_SPEC "%{posix:-lcposix} %{shlib:-lc_s} -lc -lg" diff --git a/support/cpp/i386/svr3gas.h b/support/cpp/i386/svr3gas.h deleted file mode 100644 index 401c7661..00000000 --- a/support/cpp/i386/svr3gas.h +++ /dev/null @@ -1,305 +0,0 @@ -/* Definitions for Intel 386 running system V, using gas. - Copyright (C) 1992 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "i386/gas.h" - -/* Add stuff that normally comes from i386/sysv3.h */ - -/* longjmp may fail to restore the registers if called from the same - function that called setjmp. To compensate, the compiler avoids - putting variables in registers in functions that use both setjmp - and longjmp. */ - -#define NON_SAVING_SETJMP \ - (current_function_calls_setjmp && current_function_calls_longjmp) - -/* longjmp may fail to restore the stack pointer if the saved frame - pointer is the same as the caller's frame pointer. Requiring a frame - pointer in any function that calls setjmp or longjmp avoids this - problem, unless setjmp and longjmp are called from the same function. - Since a frame pointer will be required in such a function, it is OK - that the stack pointer is not restored. */ - -#undef FRAME_POINTER_REQUIRED -#define FRAME_POINTER_REQUIRED \ - (current_function_calls_setjmp || current_function_calls_longjmp) - -/* Modify ASM_OUTPUT_LOCAL slightly to test -msvr3-shlib, adapted to gas */ -#undef ASM_OUTPUT_LOCAL -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ - do { \ - int align = exact_log2 (ROUNDED); \ - if (align > 2) align = 2; \ - if (TARGET_SVR3_SHLIB) \ - { \ - data_section (); \ - ASM_OUTPUT_ALIGN ((FILE), align == -1 ? 2 : align); \ - ASM_OUTPUT_LABEL ((FILE), (NAME)); \ - fprintf ((FILE), "\t.set .,.+%u\n", (ROUNDED)); \ - } \ - else \ - { \ - fputs (".lcomm ", (FILE)); \ - assemble_name ((FILE), (NAME)); \ - fprintf ((FILE), ",%u\n", (ROUNDED)); \ - } \ - } while (0) - -/* Add stuff that normally comes from i386/sysv3.h via svr3.h */ - -/* Define the actual types of some ANSI-mandated types. These - definitions should work for most SVR3 systems. */ - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "int" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "long int" - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE BITS_PER_WORD - -/* ??? This stuff is copied from config/svr3.h. In the future, - this file should be rewritten to include config/svr3.h - and override what isn't right. */ - -/* Support const sections and the ctors and dtors sections for g++. - Note that there appears to be two different ways to support const - sections at the moment. You can either #define the symbol - READONLY_DATA_SECTION (giving it some code which switches to the - readonly data section) or else you can #define the symbols - EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS, SELECT_SECTION, and - SELECT_RTX_SECTION. We do both here just to be on the safe side. - However, use of the const section is turned off by default - unless the specific tm.h file turns it on by defining - USE_CONST_SECTION as 1. */ - -/* Define a few machine-specific details of the implementation of - constructors. - - The __CTORS_LIST__ goes in the .init section. Define CTOR_LIST_BEGIN - and CTOR_LIST_END to contribute to the .init section an instruction to - push a word containing 0 (or some equivalent of that). - - Define ASM_OUTPUT_CONSTRUCTOR to push the address of the constructor. */ - -#define USE_CONST_SECTION 0 - -#define INIT_SECTION_ASM_OP ".section\t.init" -#define FINI_SECTION_ASM_OP ".section .fini,\"x\"" -#define CONST_SECTION_ASM_OP ".section\t.rodata, \"x\"" -#define CTORS_SECTION_ASM_OP INIT_SECTION_ASM_OP -#define DTORS_SECTION_ASM_OP FINI_SECTION_ASM_OP - -/* CTOR_LIST_BEGIN and CTOR_LIST_END are machine-dependent - because they push on the stack. */ - -#ifdef STACK_GROWS_DOWNWARD - -/* Constructor list on stack is in reverse order. Go to the end of the - list and go backwards to call constructors in the right order. */ -#define DO_GLOBAL_CTORS_BODY \ -do { \ - func_ptr *p, *beg = alloca (0); \ - for (p = beg; *p; p++) \ - ; \ - while (p != beg) \ - (*--p) (); \ -} while (0) - -#else - -/* Constructor list on stack is in correct order. Just call them. */ -#define DO_GLOBAL_CTORS_BODY \ -do { \ - func_ptr *p, *beg = alloca (0); \ - for (p = beg; *p; ) \ - (*p++) (); \ -} while (0) - -#endif /* STACK_GROWS_DOWNWARD */ - -/* Add extra sections .init and .fini, in addition to .bss from att386.h. */ - -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_const, in_bss, in_init, in_fini - -#undef EXTRA_SECTION_FUNCTIONS -#define EXTRA_SECTION_FUNCTIONS \ - CONST_SECTION_FUNCTION \ - BSS_SECTION_FUNCTION \ - INIT_SECTION_FUNCTION \ - FINI_SECTION_FUNCTION - -#define BSS_SECTION_FUNCTION \ -void \ -bss_section () \ -{ \ - if (in_section != in_bss) \ - { \ - fprintf (asm_out_file, "\t%s\n", BSS_SECTION_ASM_OP); \ - in_section = in_bss; \ - } \ -} - -#define INIT_SECTION_FUNCTION \ -void \ -init_section () \ -{ \ - if (in_section != in_init) \ - { \ - fprintf (asm_out_file, "\t%s\n", INIT_SECTION_ASM_OP); \ - in_section = in_init; \ - } \ -} - -#define FINI_SECTION_FUNCTION \ -void \ -fini_section () \ -{ \ - if (in_section != in_fini) \ - { \ - fprintf (asm_out_file, "\t%s\n", FINI_SECTION_ASM_OP); \ - in_section = in_fini; \ - } \ -} - -#define READONLY_DATA_SECTION() const_section () - -#define CONST_SECTION_FUNCTION \ -void \ -const_section () \ -{ \ - extern void text_section(); \ - if (!USE_CONST_SECTION) \ - text_section(); \ - else if (in_section != in_const) \ - { \ - fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP); \ - in_section = in_const; \ - } \ -} - -/* The ctors and dtors sections are not normally put into use - by EXTRA_SECTIONS and EXTRA_SECTION_FUNCTIONS as defined in svr3.h, - but it can't hurt to define these macros for whatever systems use them. */ -#define CTORS_SECTION_FUNCTION \ -void \ -ctors_section () \ -{ \ - if (in_section != in_ctors) \ - { \ - fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \ - in_section = in_ctors; \ - } \ -} - -#define DTORS_SECTION_FUNCTION \ -void \ -dtors_section () \ -{ \ - if (in_section != in_dtors) \ - { \ - fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \ - in_section = in_dtors; \ - } \ -} - -/* This is machine-dependent - because it needs to push something on the stack. */ -#undef ASM_OUTPUT_CONSTRUCTOR - -/* A C statement (sans semicolon) to output an element in the table of - global destructors. */ -#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ - do { \ - fini_section (); \ - fprintf (FILE, "%s\t ", ASM_LONG); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) - -/* A C statement or statements to switch to the appropriate - section for output of DECL. DECL is either a `VAR_DECL' node - or a constant of some sort. RELOC indicates whether forming - the initial value of DECL requires link-time relocations. */ - -#define SELECT_SECTION(DECL,RELOC) \ -{ \ - if (TREE_CODE (DECL) == STRING_CST) \ - { \ - if (! flag_writable_strings) \ - const_section (); \ - else \ - data_section (); \ - } \ - else if (TREE_CODE (DECL) == VAR_DECL) \ - { \ - if ((0 && RELOC) /* should be (flag_pic && RELOC) */ \ - || !TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \ - || !DECL_INITIAL (DECL) \ - || (DECL_INITIAL (DECL) != error_mark_node \ - && !TREE_CONSTANT (DECL_INITIAL (DECL)))) \ - data_section (); \ - else \ - const_section (); \ - } \ - else \ - const_section (); \ -} - -/* A C statement or statements to switch to the appropriate - section for output of RTX in mode MODE. RTX is some kind - of constant in RTL. The argument MODE is redundant except - in the case of a `const_int' rtx. Currently, these always - go into the const section. */ - -#define SELECT_RTX_SECTION(MODE,RTX) const_section() - -/* This is copied from i386/sysv3.h. */ - -/* Define a few machine-specific details of the implementation of - constructors. - - The __CTORS_LIST__ goes in the .init section. Define CTOR_LIST_BEGIN - and CTOR_LIST_END to contribute to the .init section an instruction to - push a word containing 0 (or some equivalent of that). - - ASM_OUTPUT_CONSTRUCTOR should be defined to push the address of the - constructor. */ - -#undef INIT_SECTION_ASM_OP -#define INIT_SECTION_ASM_OP ".section .init,\"x\"" - -#define CTOR_LIST_BEGIN \ - asm (INIT_SECTION_ASM_OP); \ - asm ("pushl $0") -#define CTOR_LIST_END CTOR_LIST_BEGIN - -#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ - do { \ - init_section (); \ - fprintf (FILE, "\tpushl $"); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) diff --git a/support/cpp/i386/svr3z.ifile b/support/cpp/i386/svr3z.ifile deleted file mode 100644 index 4fdbb937..00000000 --- a/support/cpp/i386/svr3z.ifile +++ /dev/null @@ -1,45 +0,0 @@ -/* - * svr3z.ifile - for collectless G++ on i386 System V. - * Leaves memory unconfigured at address 0. - * - * Install this file as $prefix/gcc-lib/TARGET/VERSION/gccz.ifile - * - * BLOCK to an offset that leaves room for many headers ( the value - * here allows for a file header, an outheader, and up to 11 section - * headers on most systems. - * BIND to an address that excludes page 0 from being mapped. The value - * used for BLOCK should be or'd into this value. Here I'm setting BLOCK - * to 0x200 and BIND to ( 0x400000 | value_used_for(BLOCK) ) - * If you are using shared libraries, watch that you don't overlap the - * address ranges assigned for shared libs. - * - * GROUP BIND to a location in the next segment. Here, the only value - * that you should change (I think) is that within NEXT, which I've set - * to my hardware segment size. You can always use a larger size, but not - * a smaller one. - */ -SECTIONS -{ - .text BIND(0x400200) BLOCK (0x200) : - { - /* plenty for room for headers */ - *(.init) - *(.text) - vfork = fork; /* I got tired of editing peoples sloppy code */ - *(.fini) - } - GROUP BIND( NEXT(0x400000) + (ADDR(.text) + (SIZEOF(.text)) % 0x1000)): - { - .data : { - __CTOR_LIST__ = . ; - . += 4 ; /* leading NULL */ - *(.ctor) - . += 4 ; /* trailing NULL */ - __DTOR_LIST__ = . ; - . += 4 ; /* leading NULL */ - *(.dtor) - . += 4 ; /* trailing NULL */ - } - .bss : { } - } -} diff --git a/support/cpp/i386/sysv3.h b/support/cpp/i386/sysv3.h deleted file mode 100644 index 8c5cfc41..00000000 --- a/support/cpp/i386/sysv3.h +++ /dev/null @@ -1,124 +0,0 @@ -/* Definitions for Intel 386 running system V. - Copyright (C) 1988 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#include "i386/i386.h" - -/* Use default settings for system V.3. */ - -#include "svr3.h" - -/* Use the ATT assembler syntax. - This overrides at least one macro (ASM_OUTPUT_LABELREF) from svr3.h. */ - -#include "i386/att.h" - -/* Use crt1.o as a startup file and crtn.o as a closing file. */ - -#define STARTFILE_SPEC \ - "%{pg:gcrt1.o%s}%{!pg:%{posix:%{p:mcrtp1.o%s}%{!p:crtp1.o%s}}%{!posix:%{p:mcrt1.o%s}%{!p:crt1.o%s}}} crtbegin.o%s\ - %{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp}" - -/* ??? There is a suggestion that -lg is needed here. - Does anyone know whether this is right? */ -#define LIB_SPEC "%{posix:-lcposix} %{shlib:-lc_s} -lc crtend.o%s crtn.o%s" - -/* Specify predefined symbols in preprocessor. */ - -#define CPP_PREDEFINES "-Dunix -Di386 -Asystem(unix) -Asystem(svr3) -Acpu(i386) -Amachine(i386)" - -#define CPP_SPEC "%{posix:-D_POSIX_SOURCE}" - -/* Writing `int' for a bitfield forces int alignment for the structure. */ - -#define PCC_BITFIELD_TYPE_MATTERS 1 - -/* Don't write a `.optim' pseudo; this assembler doesn't handle them. */ - -#undef ASM_FILE_START_1 -#define ASM_FILE_START_1(FILE) - -/* We want to be able to get DBX debugging information via -gstabs. */ - -#undef DBX_DEBUGGING_INFO -#define DBX_DEBUGGING_INFO - -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG - -/* longjmp may fail to restore the registers if called from the same - function that called setjmp. To compensate, the compiler avoids - putting variables in registers in functions that use both setjmp - and longjmp. */ - -#define NON_SAVING_SETJMP \ - (current_function_calls_setjmp && current_function_calls_longjmp) - -/* longjmp may fail to restore the stack pointer if the saved frame - pointer is the same as the caller's frame pointer. Requiring a frame - pointer in any function that calls setjmp or longjmp avoids this - problem, unless setjmp and longjmp are called from the same function. - Since a frame pointer will be required in such a function, it is OK - that the stack pointer is not restored. */ - -#undef FRAME_POINTER_REQUIRED -#define FRAME_POINTER_REQUIRED \ - (current_function_calls_setjmp || current_function_calls_longjmp) - -/* Modify ASM_OUTPUT_LOCAL slightly to test -msvr3-shlib. */ -#undef ASM_OUTPUT_LOCAL -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ - do { \ - int align = exact_log2 (ROUNDED); \ - if (align > 2) align = 2; \ - if (TARGET_SVR3_SHLIB) \ - data_section (); \ - else \ - bss_section (); \ - ASM_OUTPUT_ALIGN ((FILE), align == -1 ? 2 : align); \ - ASM_OUTPUT_LABEL ((FILE), (NAME)); \ - fprintf ((FILE), "\t.set .,.+%u\n", (ROUNDED)); \ - } while (0) - -/* Define a few machine-specific details of the implementation of - constructors. - - The __CTORS_LIST__ goes in the .init section. Define CTOR_LIST_BEGIN - and CTOR_LIST_END to contribute to the .init section an instruction to - push a word containing 0 (or some equivalent of that). - - ASM_OUTPUT_CONSTRUCTOR should be defined to push the address of the - constructor. */ - -#undef INIT_SECTION_ASM_OP -#define INIT_SECTION_ASM_OP ".section .init,\"x\"" - -#define CTOR_LIST_BEGIN \ - asm (INIT_SECTION_ASM_OP); \ - asm ("pushl $0") -#define CTOR_LIST_END CTOR_LIST_BEGIN - -#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ - do { \ - init_section (); \ - fprintf (FILE, "\tpushl $"); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) diff --git a/support/cpp/i386/sysv4.h b/support/cpp/i386/sysv4.h deleted file mode 100644 index 92fcada0..00000000 --- a/support/cpp/i386/sysv4.h +++ /dev/null @@ -1,245 +0,0 @@ -/* Target definitions for GNU compiler for Intel 80386 running System V.4 - Copyright (C) 1991 Free Software Foundation, Inc. - - Written by Ron Guilmette (rfg@netcom.com). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "i386/i386.h" /* Base i386 target machine definitions */ -#include "i386/att.h" /* Use the i386 AT&T assembler syntax */ -#include "svr4.h" /* Definitions common to all SVR4 targets */ - -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (i386 System V Release 4)"); - -/* The svr4 ABI for the i386 says that records and unions are returned - in memory. */ - -#undef RETURN_IN_MEMORY -#define RETURN_IN_MEMORY(TYPE) \ - (TYPE_MODE (TYPE) == BLKmode) - -/* Define which macros to predefine. __svr4__ is our extension. */ -/* This used to define X86, but james@bigtex.cactus.org says that - is supposed to be defined optionally by user programs--not by default. */ -#define CPP_PREDEFINES \ - "-Di386 -Dunix -D__svr4__ -Asystem(unix) -Asystem(svr4) -Acpu(i386) -Amachine(i386)" - -/* This is how to output assembly code to define a `float' constant. - We always have to use a .long pseudo-op to do this because the native - SVR4 ELF assembler is buggy and it generates incorrect values when we - try to use the .float pseudo-op instead. */ - -#undef ASM_OUTPUT_FLOAT -#define ASM_OUTPUT_FLOAT(FILE,VALUE) \ -do { long value; \ - REAL_VALUE_TO_TARGET_SINGLE ((VALUE), value); \ - if (sizeof (int) == sizeof (long)) \ - fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value); \ - else \ - fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value); \ - } while (0) - -/* This is how to output assembly code to define a `double' constant. - We always have to use a pair of .long pseudo-ops to do this because - the native SVR4 ELF assembler is buggy and it generates incorrect - values when we try to use the the .double pseudo-op instead. */ - -#undef ASM_OUTPUT_DOUBLE -#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ -do { long value[2]; \ - REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), value); \ - if (sizeof (int) == sizeof (long)) \ - { \ - fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[0]); \ - fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[1]); \ - } \ - else \ - { \ - fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[0]); \ - fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[1]); \ - } \ - } while (0) - - -#undef ASM_OUTPUT_LONG_DOUBLE -#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ -do { long value[3]; \ - REAL_VALUE_TO_TARGET_LONG_DOUBLE ((VALUE), value); \ - if (sizeof (int) == sizeof (long)) \ - { \ - fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[0]); \ - fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[1]); \ - fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[2]); \ - } \ - else \ - { \ - fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[0]); \ - fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[1]); \ - fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[2]); \ - } \ - } while (0) - -/* Output at beginning of assembler file. */ -/* The .file command should always begin the output. */ - -#undef ASM_FILE_START -#define ASM_FILE_START(FILE) \ - do { \ - output_file_directive (FILE, main_input_filename); \ - fprintf (FILE, "\t.version\t\"01.01\"\n"); \ - } while (0) - -/* Define the register numbers to be used in Dwarf debugging information. - The SVR4 reference port C compiler uses the following register numbers - in its Dwarf output code: - - 0 for %eax (gnu regno = 0) - 1 for %ecx (gnu regno = 2) - 2 for %edx (gnu regno = 1) - 3 for %ebx (gnu regno = 3) - 4 for %esp (gnu regno = 7) - 5 for %ebp (gnu regno = 6) - 6 for %esi (gnu regno = 4) - 7 for %edi (gnu regno = 5) - - The following three DWARF register numbers are never generated by - the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4 - believes these numbers have these meanings. - - 8 for %eip (no gnu equivalent) - 9 for %eflags (no gnu equivalent) - 10 for %trapno (no gnu equivalent) - - It is not at all clear how we should number the FP stack registers - for the x86 architecture. If the version of SDB on x86/svr4 were - a bit less brain dead with respect to floating-point then we would - have a precedent to follow with respect to DWARF register numbers - for x86 FP registers, but the SDB on x86/svr4 is so completely - broken with respect to FP registers that it is hardly worth thinking - of it as something to strive for compatibility with. - - The version of x86/svr4 SDB I have at the moment does (partially) - seem to believe that DWARF register number 11 is associated with - the x86 register %st(0), but that's about all. Higher DWARF - register numbers don't seem to be associated with anything in - particular, and even for DWARF regno 11, SDB only seems to under- - stand that it should say that a variable lives in %st(0) (when - asked via an `=' command) if we said it was in DWARF regno 11, - but SDB still prints garbage when asked for the value of the - variable in question (via a `/' command). - - (Also note that the labels SDB prints for various FP stack regs - when doing an `x' command are all wrong.) - - Note that these problems generally don't affect the native SVR4 - C compiler because it doesn't allow the use of -O with -g and - because when it is *not* optimizing, it allocates a memory - location for each floating-point variable, and the memory - location is what gets described in the DWARF AT_location - attribute for the variable in question. - - Regardless of the severe mental illness of the x86/svr4 SDB, we - do something sensible here and we use the following DWARF - register numbers. Note that these are all stack-top-relative - numbers. - - 11 for %st(0) (gnu regno = 8) - 12 for %st(1) (gnu regno = 9) - 13 for %st(2) (gnu regno = 10) - 14 for %st(3) (gnu regno = 11) - 15 for %st(4) (gnu regno = 12) - 16 for %st(5) (gnu regno = 13) - 17 for %st(6) (gnu regno = 14) - 18 for %st(7) (gnu regno = 15) -*/ - -#undef DBX_REGISTER_NUMBER -#define DBX_REGISTER_NUMBER(n) \ -((n) == 0 ? 0 \ - : (n) == 1 ? 2 \ - : (n) == 2 ? 1 \ - : (n) == 3 ? 3 \ - : (n) == 4 ? 6 \ - : (n) == 5 ? 7 \ - : (n) == 6 ? 5 \ - : (n) == 7 ? 4 \ - : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \ - : (-1)) - -/* The routine used to output sequences of byte values. We use a special - version of this for most svr4 targets because doing so makes the - generated assembly code more compact (and thus faster to assemble) - as well as more readable. Note that if we find subparts of the - character sequence which end with NUL (and which are shorter than - STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */ - -#undef ASM_OUTPUT_ASCII -#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \ - do \ - { \ - register unsigned char *_ascii_bytes = (unsigned char *) (STR); \ - register unsigned char *limit = _ascii_bytes + (LENGTH); \ - register unsigned bytes_in_chunk = 0; \ - for (; _ascii_bytes < limit; _ascii_bytes++) \ - { \ - register unsigned char *p; \ - if (bytes_in_chunk >= 64) \ - { \ - fputc ('\n', (FILE)); \ - bytes_in_chunk = 0; \ - } \ - for (p = _ascii_bytes; p < limit && *p != '\0'; p++) \ - continue; \ - if (p < limit && (p - _ascii_bytes) <= STRING_LIMIT) \ - { \ - if (bytes_in_chunk > 0) \ - { \ - fputc ('\n', (FILE)); \ - bytes_in_chunk = 0; \ - } \ - ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes); \ - _ascii_bytes = p; \ - } \ - else \ - { \ - if (bytes_in_chunk == 0) \ - fprintf ((FILE), "\t.byte\t"); \ - else \ - fputc (',', (FILE)); \ - fprintf ((FILE), "0x%02x", *_ascii_bytes); \ - bytes_in_chunk += 5; \ - } \ - } \ - if (bytes_in_chunk > 0) \ - fprintf ((FILE), "\n"); \ - } \ - while (0) - -/* This is how to output an element of a case-vector that is relative. - This is only used for PIC code. See comments by the `casesi' insn in - i386.md for an explanation of the expression this outputs. */ - -#undef ASM_OUTPUT_ADDR_DIFF_ELT -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ - fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE) - -/* Indicate that jump tables go in the text section. This is - necessary when compiling PIC code. */ - -#define JUMP_TABLES_IN_TEXT_SECTION diff --git a/support/cpp/i386/sysv4gdb.h b/support/cpp/i386/sysv4gdb.h deleted file mode 100644 index dd1e8f25..00000000 --- a/support/cpp/i386/sysv4gdb.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Target definitions for GNU compiler for Intel 80386 running System V.4 - with gas and gdb. */ - -/* Use stabs instead of DWARF debug format. */ -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG - -#include "i386/sysv4.h" diff --git a/support/cpp/i386/t-crtpic b/support/cpp/i386/t-crtpic deleted file mode 100644 index f5dd073a..00000000 --- a/support/cpp/i386/t-crtpic +++ /dev/null @@ -1,9 +0,0 @@ -# The pushl in CTOR initialization interferes with frame pointer elimination. - -# We need to use -fPIC when we are using gcc to compile the routines in -# crtstuff.c. This is only really needed when we are going to use gcc/g++ -# to produce a shared library, but since we don't know ahead of time when -# we will be doing that, we just always use -fPIC when compiling the -# routines in crtstuff.c. - -CRTSTUFF_T_CFLAGS = -fPIC -fno-omit-frame-pointer diff --git a/support/cpp/i386/t-crtstuff b/support/cpp/i386/t-crtstuff deleted file mode 100644 index a202df66..00000000 --- a/support/cpp/i386/t-crtstuff +++ /dev/null @@ -1,2 +0,0 @@ -# The pushl in CTOR initialization interferes with frame pointer elimination. -CRTSTUFF_T_CFLAGS = -fno-omit-frame-pointer diff --git a/support/cpp/i386/t-i386bare b/support/cpp/i386/t-i386bare deleted file mode 100644 index 2970fa71..00000000 --- a/support/cpp/i386/t-i386bare +++ /dev/null @@ -1,3 +0,0 @@ -# The i386 md has all of these taken care of, according to sef. -LIBGCC1 = -CROSS_LIBGCC1 = diff --git a/support/cpp/i386/t-iscscodbx b/support/cpp/i386/t-iscscodbx deleted file mode 100644 index 928a7589..00000000 --- a/support/cpp/i386/t-iscscodbx +++ /dev/null @@ -1,2 +0,0 @@ -# The one that comes with the system is POSIX-compliant. -LIMITS_H = diff --git a/support/cpp/i386/t-next b/support/cpp/i386/t-next deleted file mode 100644 index ec6373f9..00000000 --- a/support/cpp/i386/t-next +++ /dev/null @@ -1,9 +0,0 @@ -# libgcc1.c is not needed, since the standard library has these functions. -LIBGCC1=libgcc1.null -CROSS_LIBGCC1=libgcc1.null - -# Specify other dirs of system header files to be fixed. -OTHER_FIXINCLUDES_DIRS= /LocalDeveloper/Headers - -# is sometimes in /usr/include/ansi/limits.h. -LIMITS_H_TEST = [ -f $(SYSTEM_HEADER_DIR)/limits.h -o -f $(SYSTEM_HEADER_DIR)/ansi/limits.h ] diff --git a/support/cpp/i386/t-sol2 b/support/cpp/i386/t-sol2 deleted file mode 100644 index f79f6ca0..00000000 --- a/support/cpp/i386/t-sol2 +++ /dev/null @@ -1,32 +0,0 @@ -# we need to supply our own assembly versions of libgcc1.c files, -# since the user may not have native 'cc' available - -LIBGCC1 = libgcc1.null -CROSS_LIBGCC1 = libgcc1.null - -# gmon build rule: -gmon.o: $(srcdir)/config/i386/gmon-sol2.c $(GCC_PASSES) $(CONFIG_H) - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \ - -c $(srcdir)/config/i386/gmon-sol2.c -o gmon.o - -# Assemble startup files. -# Apparently Sun believes that assembler files don't need comments, because no -# single ASCII character is valid (tried them all). So we manually strip out -# the comments with sed. This bug may only be in the Early Access releases. -crt1.o: $(srcdir)/config/i386/sol2-c1.asm - sed -e '/^!/d' <$(srcdir)/config/i386/sol2-c1.asm >crt1.s - $(AS) -o crt1.o crt1.s -crti.o: $(srcdir)/config/i386/sol2-ci.asm - sed -e '/^!/d' <$(srcdir)/config/i386/sol2-ci.asm >crti.s - $(AS) -o crti.o crti.s -crtn.o: $(srcdir)/config/i386/sol2-cn.asm - sed -e '/^!/d' <$(srcdir)/config/i386/sol2-cn.asm >crtn.s - $(AS) -o crtn.o crtn.s - -# We need to use -fPIC when we are using gcc to compile the routines in -# crtstuff.c. This is only really needed when we are going to use gcc/g++ -# to produce a shared library, but since we don't know ahead of time when -# we will be doing that, we just always use -fPIC when compiling the -# routines in crtstuff.c. - -CRTSTUFF_T_CFLAGS = -fPIC diff --git a/support/cpp/i386/t-svr3dbx b/support/cpp/i386/t-svr3dbx deleted file mode 100644 index 51711379..00000000 --- a/support/cpp/i386/t-svr3dbx +++ /dev/null @@ -1,7 +0,0 @@ -# gas 1.38.1 supporting dbx-in-coff requires a link script. - -svr3.ifile: $(srcdir)/config/i386/svr3.ifile - rm -f svr3.ifile; cp $(srcdir)/config/i386/svr3.ifile . - -svr3z.ifile: $(srcdir)/config/i386/svr3z.ifile - rm -f svr3z.ifile; cp $(srcdir)/config/i386/svr3z.ifile . diff --git a/support/cpp/i386/t-vsta b/support/cpp/i386/t-vsta deleted file mode 100644 index 6160b7ec..00000000 --- a/support/cpp/i386/t-vsta +++ /dev/null @@ -1,2 +0,0 @@ -LIBGCC1 = libgcc1.null -CROSS_LIBGCC1 = libgcc1.null diff --git a/support/cpp/i386/t-winnt b/support/cpp/i386/t-winnt deleted file mode 100644 index e8e1a0af..00000000 --- a/support/cpp/i386/t-winnt +++ /dev/null @@ -1,2 +0,0 @@ -winnt.o: $(srcdir)/config/i386/winnt.c - $(CC) -I. -I$(srcdir) -I$(srcdir)/config -c $(srcdir)/config/i386/winnt.c diff --git a/support/cpp/i386/tmp b/support/cpp/i386/tmp deleted file mode 100644 index d36d2cdb..00000000 --- a/support/cpp/i386/tmp +++ /dev/null @@ -1,24 +0,0 @@ -/* Configuration for GNU compiler - for an Intel i386 or later processor running Windows NT 3.x. - Copyright (C) 1994 Free Software Foundation, Inc. - Contributed by Douglas B. Rupp (drupp@cs.washington.edu) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "winnt/xm-winnt.h" -#include "i386/xm-i386.h" diff --git a/support/cpp/i386/unix.h b/support/cpp/i386/unix.h deleted file mode 100644 index f38fe270..00000000 --- a/support/cpp/i386/unix.h +++ /dev/null @@ -1,148 +0,0 @@ -/* Definitions for Unix assembler syntax for the Intel 80386. - Copyright (C) 1988, 1994 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This file defines the aspects of assembler syntax - that are the same for all the i386 Unix systems - (though they may differ in non-Unix systems). */ - -/* Define some concatenation macros to concatenate an opcode - and one, two or three operands. In other assembler syntaxes - they may alter the order of ther operands. */ - -/* Note that the other files fail to use these - in some of the places where they should. */ - -#if defined(__STDC__) || defined(ALMOST_STDC) -#define AS2(a,b,c) #a " " #b "," #c -#define AS2C(b,c) " " #b "," #c -#define AS3(a,b,c,d) #a " " #b "," #c "," #d -#define AS1(a,b) #a " " #b -#else -#define AS1(a,b) "a b" -#define AS2(a,b,c) "a b,c" -#define AS2C(b,c) " b,c" -#define AS3(a,b,c,d) "a b,c,d" -#endif - -/* Define macro used to output shift-double opcodes when the shift - count is in %cl. Some assemblers require %cl as an argument; - some don't. This macro controls what to do: by default, don't - print %cl. */ -#define AS3_SHIFT_DOUBLE(a,b,c,d) AS2 (a,c,d) - -/* Output the size-letter for an opcode. - CODE is the letter used in an operand spec (L, B, W, S or Q). - CH is the corresponding lower case letter - (except if CODE is `Q' then CH is `l', unless GAS_MNEMONICS). */ -#define PUT_OP_SIZE(CODE,CH,FILE) putc (CH,(FILE)) - -/* Opcode suffix for fullword insn. */ -#define L_SIZE "l" - -/* Prefix for register names in this syntax. */ -#define RP "%" - -/* Prefix for immediate operands in this syntax. */ -#define IP "$" - -/* Indirect call instructions should use `*'. */ -#define USE_STAR 1 - -/* Prefix for a memory-operand X. */ -#define PRINT_PTR(X, FILE) - -/* Delimiters that surround base reg and index reg. */ -#define ADDR_BEG(FILE) putc('(', (FILE)) -#define ADDR_END(FILE) putc(')', (FILE)) - -/* Print an index register (whose rtx is IREG). */ -#define PRINT_IREG(FILE,IREG) \ - do \ - { fputs (",", (FILE)); PRINT_REG ((IREG), 0, (FILE)); } \ - while (0) - -/* Print an index scale factor SCALE. */ -#define PRINT_SCALE(FILE,SCALE) \ - if ((SCALE) != 1) fprintf ((FILE), ",%d", (SCALE)) - -/* Print a base/index combination. - BREG is the base reg rtx, IREG is the index reg rtx, - and SCALE is the index scale factor (an integer). */ - -#define PRINT_B_I_S(BREG,IREG,SCALE,FILE) \ - { ADDR_BEG (FILE); \ - if (BREG) PRINT_REG ((BREG), 0, (FILE)); \ - if ((IREG) != 0) \ - { PRINT_IREG ((FILE), (IREG)); \ - PRINT_SCALE ((FILE), (SCALE)); } \ - ADDR_END (FILE); } - -/* Define the syntax of pseudo-ops, labels and comments. */ - -/* String containing the assembler's comment-starter. */ - -#define ASM_COMMENT_START "/" -#define COMMENT_BEGIN "/" - -/* Output to assembler file text saying following lines - may contain character constants, extra white space, comments, etc. */ - -#define ASM_APP_ON "/APP\n" - -/* Output to assembler file text saying following lines - no longer contain unusual constructs. */ - -#define ASM_APP_OFF "/NO_APP\n" - -/* Output before read-only data. */ - -#define TEXT_SECTION_ASM_OP ".text" - -/* Output before writable (initialized) data. */ - -#define DATA_SECTION_ASM_OP ".data" - -/* Output before writable (uninitialized) data. */ - -#define BSS_SECTION_ASM_OP ".bss" - -/* This is how to output a command to make the user-level label named NAME - defined for reference from other files. */ - -#define ASM_GLOBALIZE_LABEL(FILE,NAME) \ - (fputs (".globl ", FILE), assemble_name (FILE, NAME), fputs ("\n", FILE)) - -/* By default, target has a 80387, uses IEEE compatible arithmetic, - and returns float values in the 387, ie, - (TARGET_80387 | TARGET_IEEE_FP | TARGET_FLOAT_RETURNS_IN_80387) */ - -#define TARGET_DEFAULT 0301 - -/* Floating-point return values come in the FP register. */ - -#define VALUE_REGNO(MODE) \ - (GET_MODE_CLASS (MODE) == MODE_FLOAT \ - && TARGET_FLOAT_RETURNS_IN_80387 ? FIRST_FLOAT_REG : 0) - -/* 1 if N is a possible register number for a function value. */ - -#define FUNCTION_VALUE_REGNO_P(N) \ - ((N) == 0 || ((N)== FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387)) - diff --git a/support/cpp/i386/v3gas.h b/support/cpp/i386/v3gas.h deleted file mode 100644 index fe558d26..00000000 --- a/support/cpp/i386/v3gas.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Definitions for Intel 386 running system V, using gas. - Copyright (C) 1992, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include - -/* Add stuff that normally comes from i386v.h */ - -/* longjmp may fail to restore the registers if called from the same - function that called setjmp. To compensate, the compiler avoids - putting variables in registers in functions that use both setjmp - and longjmp. */ - -#define NON_SAVING_SETJMP \ - (current_function_calls_setjmp && current_function_calls_longjmp) - -/* longjmp may fail to restore the stack pointer if the saved frame - pointer is the same as the caller's frame pointer. Requiring a frame - pointer in any function that calls setjmp or longjmp avoids this - problem, unless setjmp and longjmp are called from the same function. - Since a frame pointer will be required in such a function, it is OK - that the stack pointer is not restored. */ - -#undef FRAME_POINTER_REQUIRED -#define FRAME_POINTER_REQUIRED \ - (current_function_calls_setjmp || current_function_calls_longjmp) - -/* Modify ASM_OUTPUT_LOCAL slightly to test -msvr3-shlib, adapted to gas */ -#undef ASM_OUTPUT_LOCAL -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ - do { \ - int align = exact_log2 (ROUNDED); \ - if (align > 2) align = 2; \ - if (TARGET_SVR3_SHLIB) \ - { \ - data_section (); \ - ASM_OUTPUT_ALIGN ((FILE), align == -1 ? 2 : align); \ - ASM_OUTPUT_LABEL ((FILE), (NAME)); \ - fprintf ((FILE), "\t.set .,.+%u\n", (ROUNDED)); \ - } \ - else \ - { \ - fputs (".lcomm ", (FILE)); \ - assemble_name ((FILE), (NAME)); \ - fprintf ((FILE), ",%u\n", (ROUNDED)); \ - } \ - } while (0) - -/* Add stuff that normally comes from i386v.h via svr3.h */ - -/* Define the actual types of some ANSI-mandated types. These - definitions should work for most SVR3 systems. */ - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "int" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "long int" - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE BITS_PER_WORD diff --git a/support/cpp/i386/vsta.h b/support/cpp/i386/vsta.h deleted file mode 100644 index ee7fab91..00000000 --- a/support/cpp/i386/vsta.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Configuration for an i386 running VSTa micro-kernel. - Copyright (C) 1994 Free Software Foundation, Inc. - Contributed by Rob Savoye (rob@cygnus.com). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define YES_UNDERSCORES - -#include "i386/gas.h" - -#ifdef CPP_PREDEFINES -#undef CPP_PREDEFINES -#endif -#define CPP_PREDEFINES "-Dunix -Di386 -DVSTA \ - -Asystem(unix) -Asystem(vsta) -Acpu(i386) -Amachine(i386)" - -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_ctor, in_dtor - -#undef EXTRA_SECTION_FUNCTIONS -#define EXTRA_SECTION_FUNCTIONS \ - CTOR_SECTION_FUNCTION \ - DTOR_SECTION_FUNCTION - -#define CTOR_SECTION_FUNCTION \ -void \ -ctor_section () \ -{ \ - if (in_section != in_ctor) \ - { \ - fprintf (asm_out_file, "\t.section .ctor\n"); \ - in_section = in_ctor; \ - } \ -} - -#define DTOR_SECTION_FUNCTION \ -void \ -dtor_section () \ -{ \ - if (in_section != in_dtor) \ - { \ - fprintf (asm_out_file, "\t.section .dtor\n"); \ - in_section = in_dtor; \ - } \ -} - -#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ - do { \ - ctor_section (); \ - fprintf (FILE, "%s\t", ASM_LONG); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) - -#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ - do { \ - dtor_section (); \ - fprintf (FILE, "%s\t", ASM_LONG); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) - - diff --git a/support/cpp/i386/win-nt.h b/support/cpp/i386/win-nt.h deleted file mode 100644 index aea1cebd..00000000 --- a/support/cpp/i386/win-nt.h +++ /dev/null @@ -1,161 +0,0 @@ -/* Operating system specific defines to be used when targeting GCC for - Windows NT 3.x on an i386. - Copyright (C) 1994, 1995 Free Software Foundation, Inc. - Contributed by Douglas B. Rupp (drupp@cs.washington.edu). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define YES_UNDERSCORES - -#include "i386/gas.h" - -#ifdef CPP_PREDEFINES -#undef CPP_PREDEFINES -#endif -#if 0 -/* The whole configuration system should be fixed; we really shouldn't - * include this file at all. - * - * But at least let's not pretend we're Microsoft C version 8 running - * on Windows NT, eh? - */ -#define CPP_PREDEFINES "-Dunix -Di386 -DWIN32 -D_WIN32 \ - -DWINNT -D_M_IX86=300 -D_X86_=1 -D__STDC__=0 -DALMOST_STDC -D_MSC_VER=800 \ - -D__stdcall=__attribute__((__stdcall__)) \ - -D__cdecl=__attribute__((__cdecl__)) \ - -D_cdecl=__attribute__((__cdecl__)) \ - -Asystem(unix) -Asystem(winnt) -Acpu(i386) -Amachine(i386)" -#else -#define CPP_PREDEFINES "-DSDCC" -#endif -#define SIZE_TYPE "unsigned int" -#define PTRDIFF_TYPE "int" -#define WCHAR_UNSIGNED 1 -#define WCHAR_TYPE_SIZE 16 -#define WCHAR_TYPE "short unsigned int" -#undef LONG_DOUBLE_TYPE_SIZE -#define LONG_DOUBLE_TYPE_SIZE 64 -#define HAVE_ATEXIT 1 - -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_ctor, in_dtor - -#undef EXTRA_SECTION_FUNCTIONS -#define EXTRA_SECTION_FUNCTIONS \ - CTOR_SECTION_FUNCTION \ - DTOR_SECTION_FUNCTION - -#define CTOR_SECTION_FUNCTION \ -void \ -ctor_section () \ -{ \ - if (in_section != in_ctor) \ - { \ - fprintf (asm_out_file, "\t.section .ctor\n"); \ - in_section = in_ctor; \ - } \ -} - -#define DTOR_SECTION_FUNCTION \ -void \ -dtor_section () \ -{ \ - if (in_section != in_dtor) \ - { \ - fprintf (asm_out_file, "\t.section .dtor\n"); \ - in_section = in_dtor; \ - } \ -} - -#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ - do { \ - ctor_section (); \ - fprintf (FILE, "%s\t", ASM_LONG); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) - -#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ - do { \ - dtor_section (); \ - fprintf (FILE, "%s\t", ASM_LONG); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) - -/* Define this macro if references to a symbol must be treated - differently depending on something about the variable or - function named by the symbol (such as what section it is in). - - On i386, if using PIC, mark a SYMBOL_REF for a non-global symbol - so that we may access it directly in the GOT. - - On i386 running Windows NT, modify the assembler name with a suffix - consisting of an atsign (@) followed by string of digits that represents - the number of bytes of arguments passed to the function, if it has the - attribute STDCALL. */ - -#ifdef ENCODE_SECTION_INFO -#undef ENCODE_SECTION_INFO -#define ENCODE_SECTION_INFO(DECL) \ -do \ - { \ - if (flag_pic) \ - { \ - rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ - ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \ - SYMBOL_REF_FLAG (XEXP (rtl, 0)) \ - = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ - || ! TREE_PUBLIC (DECL)); \ - } \ - if (TREE_CODE (DECL) == FUNCTION_DECL) \ - if (lookup_attribute ("stdcall", \ - TYPE_ATTRIBUTES (TREE_TYPE (DECL)))) \ - XEXP (DECL_RTL (DECL), 0) = \ - gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (DECL)); \ - } \ -while (0) -#endif - -/* The global __fltused is necessary to cause the printf/scanf routines - for outputting/inputting floating point numbers to be loaded. Since this - is kind of hard to detect, we just do it all the time. */ - -#ifdef ASM_FILE_START -#undef ASM_FILE_START -#endif -#define ASM_FILE_START(FILE) \ - do { fprintf (FILE, "\t.file\t"); \ - output_quoted_string (FILE, dump_base_name); \ - fprintf (FILE, "\n"); \ - fprintf (FILE, ".global\t__fltused\n"); \ - } while (0) - -/* if the switch "-mwindows" is passed to ld, then specify to the Microsoft - linker the proper switches and libraries to build a graphical program */ - -#undef LIB_SPEC -#define LIB_SPEC "%{mwindows:-subsystem windows -e _WinMainCRTStartup \ - USER32.LIB%s GDI32.LIB%s COMDLG32.LIB%s WINSPOOL.LIB%s} \ - %{!mwindows:-subsystem console -e _mainCRTStartup} \ - %{mcrtmt:LIBCMT.LIB%s KERNEL32.LIB%s ADVAPI32.LIB%s} \ - %{!mcrtmt:LIBC.LIB%s KERNEL32.LIB%s ADVAPI32.LIB%s} \ - %{v}" - -#include "winnt/win-nt.h" - diff --git a/support/cpp/i386/winnt.c b/support/cpp/i386/winnt.c deleted file mode 100644 index 3a7ebf1b..00000000 --- a/support/cpp/i386/winnt.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Subroutines for insn-output.c for Windows NT. - Contributed by Douglas Rupp (drupp@cs.washington.edu) - Copyright (C) 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include -#include "config.h" -#include "rtl.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "output.h" -#include "tree.h" -#include "flags.h" - -/* Return string which is the former assembler name modified with a - suffix consisting of an atsign (@) followed by the number of bytes of - arguments */ - -char * -gen_stdcall_suffix (decl) - tree decl; -{ - int total = 0; - char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - char *newsym; - - if (TYPE_ARG_TYPES (TREE_TYPE (decl))) - if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl)))) - == void_type_node) - { - tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl)); - - while (TREE_VALUE (formal_type) != void_type_node) - { - total += TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type))); - formal_type = TREE_CHAIN (formal_type); - } - } - - newsym = xmalloc (strlen (asmname) + 10); - sprintf (newsym, "%s@%d", asmname, total/BITS_PER_UNIT); - return IDENTIFIER_POINTER (get_identifier (newsym)); -} - diff --git a/support/cpp/i386/x-aix b/support/cpp/i386/x-aix deleted file mode 100644 index b191e48f..00000000 --- a/support/cpp/i386/x-aix +++ /dev/null @@ -1,12 +0,0 @@ -# There is an alloca in -lbsd, but it is limited to 32K -ALLOCA = alloca.o - -# If you are running out of memory while compiling gcc, with the standard -# /bin/cc uncomment MALLOCLIB line. That version of malloc is slower but -# has less overhead than the one in libc. -#MALLOCLIB = -lmalloc - -# Uncomment out the next line if you want to link with the shareable libc_s. -#CLIB_S = -lc_s - -CLIB = -lld $(MALLOCLIB) $(CLIB_S) diff --git a/support/cpp/i386/x-freebsd b/support/cpp/i386/x-freebsd deleted file mode 100644 index a9b13ba5..00000000 --- a/support/cpp/i386/x-freebsd +++ /dev/null @@ -1,3 +0,0 @@ -# Don't run fixproto -STMP_FIXPROTO = -CLIB=-lgnumalloc diff --git a/support/cpp/i386/x-isc b/support/cpp/i386/x-isc deleted file mode 100644 index ea65ec88..00000000 --- a/support/cpp/i386/x-isc +++ /dev/null @@ -1,3 +0,0 @@ -CLIB = -lPW -lcposix -X_CFLAGS = -D_POSIX_SOURCE -ENQUIRE_LDFLAGS = -posix $(LDFLAGS) diff --git a/support/cpp/i386/x-isc3 b/support/cpp/i386/x-isc3 deleted file mode 100644 index 527cca81..00000000 --- a/support/cpp/i386/x-isc3 +++ /dev/null @@ -1,4 +0,0 @@ -CLIB = -lPW -# One person said it needs -DPOSIX_JC, but daa@CERF.NET says no. -X_CFLAGS = -D_SYSV3 -Xp -ENQUIRE_LDFLAGS = $(LDFLAGS) diff --git a/support/cpp/i386/x-ncr3000 b/support/cpp/i386/x-ncr3000 deleted file mode 100644 index 4ae168b1..00000000 --- a/support/cpp/i386/x-ncr3000 +++ /dev/null @@ -1,34 +0,0 @@ -# Makefile additions for the NCR3000 as host system. - -# Using -O with the AT&T compiler fails, with a message about a missing -# /usr/ccs/lib/optim pass. So override the default in Makefile.in - -CCLIBFLAGS= - -## Supposedly not needed now that xm-sysv4.h includes alloc.h for Metaware. -### NCR3000 ships with a MetaWare compiler installed as CC, which chokes and -### dies all over the place on GCC source. However, the AT&T compiler, -### crusty as it is, can be used to bootstrap GCC. It can be found in -### /usr/ccs/ATT/cc. It is also used to compile the things that should -### not be compiled with GCC. -## -##CC = /usr/ccs/ATT/cc -##OLDCC = /usr/ccs/ATT/cc - -# The rest is just x-i386v4. - -# Some versions of SVR4 have an alloca in /usr/ucblib/libucb.a, and if we are -# careful to link that in after libc we can use it, but since newer versions of -# SVR4 are dropping libucb, it is better to just use the portable C version for -# bootstrapping. Do this by defining ALLOCA. - -ALLOCA = alloca.o - -# We used to build all stages *without* shared libraries because that may make -# debugging the compiler easier (until there is a GDB which supports -# both Dwarf *and* svr4 shared libraries). - -# But james@bigtex.cactus.org says that redefining GCC_CFLAGS causes trouble, -# and that it is easy enough to debug using shared libraries. -# CCLIBFLAGS=-Bstatic -dn -g -# GCC_CFLAGS=-static -g -O2 -B./ diff --git a/support/cpp/i386/x-next b/support/cpp/i386/x-next deleted file mode 100644 index a16b918e..00000000 --- a/support/cpp/i386/x-next +++ /dev/null @@ -1,3 +0,0 @@ -# Make assignments for compiling on NeXT with their compiler version. -CC=cc -traditional-cpp -OLDCC=cc -traditional-cpp diff --git a/support/cpp/i386/x-osfrose b/support/cpp/i386/x-osfrose deleted file mode 100644 index a419bdb7..00000000 --- a/support/cpp/i386/x-osfrose +++ /dev/null @@ -1,31 +0,0 @@ -# Define CC and OLDCC as the same, so that the tests: -# if [ x"$(OLDCC)" = x"$(CC)" ] ... -# -# will succeed (if OLDCC != CC, it is assumed that GCC is -# being used in secondary stage builds). - -BUILD = -CC = $(OLDCC) -CLIB = -lld -X_CFLAGS = $(DEB_OPT) $(MSTATS) $(SHLIB) $(X_DEFINES) -X_CFLAGS_NODEBUG = $(NO_DEBUG) $(MSTATS) $(OPT) $(PROFILE) $(SHLIB) $(X_DEFINES) $(XCFLAGS) -CPP_ABORT = # -Dabort=fancy_abort -CPPFLAGS = $(CPP_ABORT) $(SYSTEM_INCLUDES) -DEB_OPT = $(OPT) $(DEBUG) $(PROFILE) -DEBUG = -DEBUG_COLLECT = # -DDEBUG -CCLIBFLAGS = -O -DNO_HALF_PIC -GCC_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) -B./ -DPOSIX -DNO_HALF_PIC -INSTALL = installbsd -c -LDFLAGS = -MSTATS = # -mstats -OLDCC = /usr/ccs/gcc/gcc -OPT = -O -PROFILE = -SHLIB = -pic-none -SYSTEM_INCLUDES = # -I${BUILD}/usr/include -X_DEFINES = -Dvfork=fork - -libdir = /usr/ccs -mandir = /usr/ccs/gcc/$(target)/$(version) -bindir = /usr/ccs/gcc/$(target)/$(version) diff --git a/support/cpp/i386/x-sco b/support/cpp/i386/x-sco deleted file mode 100644 index f7f14e9f..00000000 --- a/support/cpp/i386/x-sco +++ /dev/null @@ -1,7 +0,0 @@ -RANLIB = : -RANLIB_TEST = false -CC = rcc $(RCCFLAGS) -OLDCC = rcc $(RCCFLAGS) -RCCFLAGS = -Dunix -Di386 -DM_UNIX -DM_I386 -DNULL=0 -CCLIBFLAGS = -CLIB = -lmalloc -lPW diff --git a/support/cpp/i386/x-sco4 b/support/cpp/i386/x-sco4 deleted file mode 100644 index be6080f8..00000000 --- a/support/cpp/i386/x-sco4 +++ /dev/null @@ -1,10 +0,0 @@ -RANLIB = : -RANLIB_TEST = false -CC = rcc $(RCCFLAGS) -OLDCC = rcc $(RCCFLAGS) -RCCFLAGS = -Dunix -Di386 -DM_UNIX -DM_I386 -DNULL=0 -CCLIBFLAGS = -CLIB = -lmalloc -lPW - -# See all the declarations. -FIXPROTO_DEFINES = -D_XOPEN_SOURCE diff --git a/support/cpp/i386/x-sysv3 b/support/cpp/i386/x-sysv3 deleted file mode 100644 index a1391df8..00000000 --- a/support/cpp/i386/x-sysv3 +++ /dev/null @@ -1 +0,0 @@ -CLIB=-lPW diff --git a/support/cpp/i386/x-vsta b/support/cpp/i386/x-vsta deleted file mode 100644 index e2279a4b..00000000 --- a/support/cpp/i386/x-vsta +++ /dev/null @@ -1 +0,0 @@ -CLIB=-lm diff --git a/support/cpp/i386/xm-aix.h b/support/cpp/i386/xm-aix.h deleted file mode 100644 index 5e5d4028..00000000 --- a/support/cpp/i386/xm-aix.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Configuration for GNU C-compiler for IBM PS/2 running AIX/386. - Copyright (C) 1988, 1993 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define USG - -#undef TRUE -#undef FALSE - -#include "i386/xm-i386.h" - -#define bcopy(a,b,c) memcpy (b,a,c) -#define bzero(a,b) memset (a,0,b) -#define bcmp(a,b,c) memcmp (a,b,c) - -/* If not compiled with GNU C, use the portable alloca. */ -#ifndef __GNUC__ -#define USE_C_ALLOCA -#endif - -#define HAVE_PUTENV diff --git a/support/cpp/i386/xm-bsd386.h b/support/cpp/i386/xm-bsd386.h deleted file mode 100644 index 9deb7ef6..00000000 --- a/support/cpp/i386/xm-bsd386.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Configuration for GCC for Intel i386 running BSDI's BSD/386 as host. */ - -#include "i386/xm-i386.h" - -#define HAVE_STRERROR - diff --git a/support/cpp/i386/xm-dos.h b/support/cpp/i386/xm-dos.h deleted file mode 100644 index 1dd0c013..00000000 --- a/support/cpp/i386/xm-dos.h +++ /dev/null @@ -1,20 +0,0 @@ -#include "i386/xm-i386.h" - -/* Inhibit cccp.c's definition of putenv. */ -#define HAVE_PUTENV - -/* Use semicolons to separate elements of a path. */ -#define PATH_SEPARATOR ';' - -/* Use backslashs to separate levels of directory. */ -#define DIR_SEPARATOR '\\' - -/* Suffix for executable file names. */ -#define EXECUTABLE_SUFFIX ".exe" - -#define MKTEMP_EACH_FILE 1 - -#define NO_PRECOMPILES 1 - -/* sys_errlist proto in cccp.c doesn't match djgpp */ -#define HAVE_STRERROR diff --git a/support/cpp/i386/xm-freebsd.h b/support/cpp/i386/xm-freebsd.h deleted file mode 100644 index 007a609f..00000000 --- a/support/cpp/i386/xm-freebsd.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Configuration for GCC for Intel i386 running FreeBSD as host. */ - -#include -#include diff --git a/support/cpp/i386/xm-gnu.h b/support/cpp/i386/xm-gnu.h deleted file mode 100644 index 0b5985f9..00000000 --- a/support/cpp/i386/xm-gnu.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Configuration for GCC for Intel i386 running GNU as host. */ - -#include -#include - diff --git a/support/cpp/i386/xm-i386.h b/support/cpp/i386/xm-i386.h deleted file mode 100644 index acc16576..00000000 --- a/support/cpp/i386/xm-i386.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Configuration for GNU C-compiler for Intel 80386. - Copyright (C) 1988, 1993 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifndef i386 -#define i386 -#endif - -/* #defines that need visibility everywhere. */ -#define FALSE 0 -#define TRUE 1 - -/* This describes the machine the compiler is hosted on. */ -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 32 -#define HOST_BITS_PER_LONGLONG 64 - -/* Arguments to use with `exit'. */ -#define SUCCESS_EXIT_CODE 0 -#define FATAL_EXIT_CODE 33 - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ - -#include "tm.h" diff --git a/support/cpp/i386/xm-isc.h b/support/cpp/i386/xm-isc.h deleted file mode 100644 index 7a0a47c4..00000000 --- a/support/cpp/i386/xm-isc.h +++ /dev/null @@ -1,6 +0,0 @@ -#include "i386/xm-sysv3.h" - -#ifndef REAL_ARITHMETIC -#define REAL_VALUE_ATOF(x, mode) strtod ((x), (char **)0) -extern double strtod (); -#endif diff --git a/support/cpp/i386/xm-linux.h b/support/cpp/i386/xm-linux.h deleted file mode 100644 index d5e97b8a..00000000 --- a/support/cpp/i386/xm-linux.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Configuration for GCC for Intel i386 running Linux. - Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. - Contributed by H.J. Lu (hjl@nynexst.com) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include -/* #include */ - diff --git a/support/cpp/i386/xm-lynx.h b/support/cpp/i386/xm-lynx.h deleted file mode 100644 index 359e41bb..00000000 --- a/support/cpp/i386/xm-lynx.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Configuration for GNU C-compiler for i386 platforms running LynxOS. - Copyright (C) 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include - -/* This describes the machine the compiler is hosted on. */ -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 32 -#define HOST_BITS_PER_LONGLONG 64 - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ - -#include "tm.h" diff --git a/support/cpp/i386/xm-netbsd.h b/support/cpp/i386/xm-netbsd.h deleted file mode 100644 index 3a9f3241..00000000 --- a/support/cpp/i386/xm-netbsd.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Configuration for GCC for Intel i386 running NetBSD as host. */ - -#include -#include diff --git a/support/cpp/i386/xm-next.h b/support/cpp/i386/xm-next.h deleted file mode 100644 index bf903281..00000000 --- a/support/cpp/i386/xm-next.h +++ /dev/null @@ -1,5 +0,0 @@ -#include "i386/xm-i386.h" - -/* malloc does better with chunks the size of a page. */ - -#define OBSTACK_CHUNK_SIZE (getpagesize ()) diff --git a/support/cpp/i386/xm-os2.h b/support/cpp/i386/xm-os2.h deleted file mode 100644 index 5ff2899c..00000000 --- a/support/cpp/i386/xm-os2.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Configuration for GNU compiler - for an Intel i386 or later processor running OS/2 2.x. - Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. - Contributed by Samuel Figueroa (figueroa@cs.nyu.edu) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifndef OS2 -#define OS2 -#endif - -#ifdef __IBMC__ -#include /* this defines alloca */ -#define USG -#define ONLY_INT_FIELDS -#define HAVE_PUTENV -#define USE_PROTOTYPES 1 -#define bcmp(a,b,c) memcmp (a,b,c) -#define bcopy(a,b,c) memcpy (b,a,c) -#define bzero(a,b) memset (a,0,b) -#define index strchr -#define rindex strrchr -#define strcasecmp stricmp -#define kill(a,b) raise(b) -#define mktemp tmpnam -#else -#define ____386BSD____ -int spawnv (int modeflag, char *path, char *argv[]); -int spawnvp (int modeflag, char *path, char *argv[]); -#endif /* __IBMC__ */ - -#ifndef PATH_SEPARATOR -#define PATH_SEPARATOR ';' -#endif -#ifndef DIR_SEPARATOR -#define DIR_SEPARATOR '\\' -#endif - -#define EXECUTABLE_SUFFIX ".exe" -#define OBJECT_SUFFIX ".obj" - -#include "i386/xm-i386.h" diff --git a/support/cpp/i386/xm-osf.h b/support/cpp/i386/xm-osf.h deleted file mode 100644 index fda50d98..00000000 --- a/support/cpp/i386/xm-osf.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Configuration for GNU C-compiler for 386 running OSF/1 - Copyright (C) 1994 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#undef TRUE -#undef FALSE - -#include "i386/xm-i386.h" - -#define bcopy(a,b,c) memcpy (b,a,c) -#define bzero(a,b) memset (a,0,b) -#define bcmp(a,b,c) memcmp (a,b,c) - -#define HAVE_PUTENV -#define HAVE_VPRINTF - diff --git a/support/cpp/i386/xm-sco.h b/support/cpp/i386/xm-sco.h deleted file mode 100644 index 01a63d90..00000000 --- a/support/cpp/i386/xm-sco.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Configuration for GCC for Intel i386 running SCO. */ - -#include "i386/xm-sysv3.h" - -/* On SCO 3.2.1, ldexp rejects values outside [0.5, 1). */ - -#define BROKEN_LDEXP - -/* Big buffers improve performance. */ - -#define IO_BUFFER_SIZE (0x8000 - 1024) - -/* SCO has a very small ARG_MAX. */ -#define SMALL_ARG_MAX - -#ifndef __GNUC__ -/* The SCO compiler gets it wrong, and treats enumerated bitfields - as signed quantities, making it impossible to use an 8-bit enum - for compiling GNU C++. */ -#define ONLY_INT_FIELDS 1 -#define CODE_FIELD_BUG 1 -#endif diff --git a/support/cpp/i386/xm-sun.h b/support/cpp/i386/xm-sun.h deleted file mode 100644 index d2e714ec..00000000 --- a/support/cpp/i386/xm-sun.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Configuration for GNU C-compiler for Intel 80386 running SunOS 4.0. - Copyright (C) 1988 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define USG - -#include "i386/xm-i386.h" - -#define bcopy(a,b,c) memcpy (b,a,c) -#define bzero(a,b) memset (a,0,b) -#define bcmp(a,b,c) memcmp (a,b,c) diff --git a/support/cpp/i386/xm-sysv3.h b/support/cpp/i386/xm-sysv3.h deleted file mode 100644 index 72078bb1..00000000 --- a/support/cpp/i386/xm-sysv3.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Configuration for GCC for Intel i386 running System V Release 3. */ - -#include "i386/xm-i386.h" -#include "xm-svr3.h" diff --git a/support/cpp/i386/xm-sysv4.h b/support/cpp/i386/xm-sysv4.h deleted file mode 100644 index 49d52b4e..00000000 --- a/support/cpp/i386/xm-sysv4.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Configuration for GCC for Intel i386 running System V Release 4. */ - -#include "i386/xm-i386.h" -#include "xm-svr4.h" - -/* If not compiled with GNU C, use the portable alloca. */ -#ifndef __GNUC__ -#define USE_C_ALLOCA -#endif -#ifdef __HIGHC__ -#include /* for MetaWare High-C on NCR System 3000 */ -#endif - -/* Univel, at least, has a small ARG_MAX. Defining this is harmless - except for causing extra stat calls in the driver program. */ -#define SMALL_ARG_MAX diff --git a/support/cpp/i386/xm-vsta.h b/support/cpp/i386/xm-vsta.h deleted file mode 100644 index bb333aea..00000000 --- a/support/cpp/i386/xm-vsta.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Configuration for GNU C-compiler for Intel 80386. - Copyright (C) 1994 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define NO_STAB_H - -#include "i386/xm-i386.h" - -/* Use semicolons to separate elements of a path. */ -#define PATH_SEPARATOR ';' diff --git a/support/cpp/i386/xm-winnt.h b/support/cpp/i386/xm-winnt.h deleted file mode 100644 index d36d2cdb..00000000 --- a/support/cpp/i386/xm-winnt.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Configuration for GNU compiler - for an Intel i386 or later processor running Windows NT 3.x. - Copyright (C) 1994 Free Software Foundation, Inc. - Contributed by Douglas B. Rupp (drupp@cs.washington.edu) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "winnt/xm-winnt.h" -#include "i386/xm-i386.h" diff --git a/support/cpp/sdcpp.dsp b/support/cpp/sdcpp.dsp deleted file mode 100644 index 40b66318..00000000 --- a/support/cpp/sdcpp.dsp +++ /dev/null @@ -1,125 +0,0 @@ -# Microsoft Developer Studio Project File - Name="sdcpp" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=sdcpp - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "sdcpp.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "sdcpp.mak" CFG="sdcpp - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "sdcpp - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "" -# PROP Intermediate_Dir "" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /G3 /ML /W3 /Gm /GX /ZI /Od /I "..\util" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR"./" /J /FD /GZ /c -# SUBTRACT CPP /WX -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo /o".\sdcpp.bsc" -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /version:2.2 /subsystem:console /debug /machine:I386 /out:"..\..\bin\sdcpp.exe" /pdbtype:sept -# SUBTRACT LINK32 /incremental:no -# Begin Target - -# Name "sdcpp - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=cppalloc.c -# End Source File -# Begin Source File - -SOURCE=cpperror.c -# End Source File -# Begin Source File - -SOURCE=cppexp.c -# End Source File -# Begin Source File - -SOURCE=cpphash.c -# End Source File -# Begin Source File - -SOURCE=cpplib.c -# End Source File -# Begin Source File - -SOURCE=cppmain.c -# End Source File -# Begin Source File - -SOURCE=..\Util\NewAlloc.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\config.h -# End Source File -# Begin Source File - -SOURCE=.\cpphash.h -# End Source File -# Begin Source File - -SOURCE=.\cpplib.h -# End Source File -# Begin Source File - -SOURCE=..\Util\newalloc.h -# End Source File -# Begin Source File - -SOURCE=.\tm.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# Begin Group "Test" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\test\cpptest.c -# PROP Exclude_From_Build 1 -# End Source File -# End Group -# End Target -# End Project diff --git a/support/cpp/support.c b/support/cpp/support.c deleted file mode 100644 index a8808f88..00000000 --- a/support/cpp/support.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Support functions for mingw32 and probably Borland C - */ -#include - -#ifdef __MINGW32__ -void bzero(void *s, size_t n) -{ - memset(s, 0, n); -} - -void bcopy(const void *src, void *dest, size_t n) -{ - memcpy(dest, src, n); -} - -int bcmp(const void *s1, const void *s2, size_t n) -{ - return memcmp(s1, s2, n); -} - -char *index(const char *s, int c) -{ - return strchr(s, c); -} - -char *rindex(const char *s, int c) -{ - return strrchr(s, c); -} -#endif diff --git a/support/cpp/tm.h b/support/cpp/tm.h deleted file mode 100644 index 0fb54981..00000000 --- a/support/cpp/tm.h +++ /dev/null @@ -1 +0,0 @@ -#include "i386/win-nt.h" diff --git a/support/cpp/winnt/Makefile b/support/cpp/winnt/Makefile deleted file mode 100644 index 1a8f5824..00000000 --- a/support/cpp/winnt/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# Makefile generated by "config-nt.bat" -all.nt: cpp.exe cc1.exe cc1obj.exe xgcc.exe ld.exe stmp-headers libgcc.lib stmp-float_h specs stamp-objlist -lang.mostlyclean: -lang.clean: -lang.distclean: -lang.realclean: diff --git a/support/cpp/winnt/config-nt.bat b/support/cpp/winnt/config-nt.bat deleted file mode 100755 index 59a00863..00000000 --- a/support/cpp/winnt/config-nt.bat +++ /dev/null @@ -1,51 +0,0 @@ -echo Configuring GCC for Windows NT on %2 -rem This batch file assumes a unix-type "sed" program - -echo #include "%2/xm-winnt.h" >config.h -echo #include "%2/xm-winnt.h" >hconfig.h -echo #include "%2/xm-winnt.h" >tconfig.h -echo #include "%2/win-nt.h" >tm.h - -rem This batch file assumes a unix-type "sed" program - -echo # Makefile generated by "config-nt.bat"> Makefile -echo all.nt: cpp.exe cc1.exe cc1obj.exe xgcc.exe ld.exe stmp-headers libgcc.lib stmp-float_h specs stamp-objlist>> Makefile -sed -f config/%2/config-nt.sed -f config/winnt/config-nt.sed Makefile.in >> Makefile - -set LANG= - -echo # >specs.h -echo # >options.h - -if not exist cp\make-lang.in goto no_cp -if exist cp\lang-specs.h echo #include "cp/lang-specs.h">>specs.h -if exist cp\lang-options.h echo #include "cp/lang-options.h">>options.h -sed -f config/%2/config-nt.sed -f config/winnt/config-nt.sed cp\make-lang.in >> Makefile -sed -f config/%2/config-nt.sed -f config/winnt/config-nt.sed cp\makefile.in > cp\Makefile -set LANG=%LANG% c++.# -:no_cp - -if not exist ada\make-lang.in goto no_ada -if exist ada\lang-specs.h echo #include "ada/lang-specs.h">>specs.h -if exist ada\lang-options.h echo #include "ada/lang-options.h">>options.h -sed -f config/%2/config-nt.sed -f config/winnt/config-nt.sed ada\make-lang.in >> Makefile -sed -f config/%2/config-nt.sed -f config/winnt/config-nt.sed ada\makefile.in > ada\Makefile -set LANG=%LANG% ada.# -:no_ada - -if not exist f\make-lang.in goto no_f -if exist f\lang-specs.h echo #include "f/lang-specs.h">>specs.h -if exist f\lang-options.h echo #include "f/lang-options.h">>options.h -sed -f config/%2/config-nt.sed -f config/winnt/config-nt.sed f\make-lang.in >> Makefile -sed -f config/%2/config-nt.sed -f config/winnt/config-nt.sed f\makefile.in > f\Makefile -set LANG=%LANG% f.# -:no_f - -echo lang.mostlyclean: %LANG% | sed "s/#/mostlyclean/g" >> Makefile -echo lang.clean: %LANG% | sed "s/#/clean/g" >> Makefile -echo lang.distclean: %LANG% | sed "s/#/distclean/g" >> Makefile -echo lang.realclean: %LANG% | sed "s/#/realclean/g" >> Makefile - -echo #define MULTILIB_SELECT ". ;" > multilib.h1 -copy multilib.h1 multilib.h -del multilib.h1 diff --git a/support/cpp/winnt/config-nt.sed b/support/cpp/winnt/config-nt.sed deleted file mode 100644 index d70f5c6c..00000000 --- a/support/cpp/winnt/config-nt.sed +++ /dev/null @@ -1,130 +0,0 @@ -/^Makefile/,/^ rm -f config.run/d -s/rm -f/del/ -s/|| cp/|| copy/ -/^config.status/,/ fi/d -s/config.status//g -s/\/dev\/null/NUL/g -s/$(srcdir)\/c-parse/c-parse/g -s/$(srcdir)\/objc-parse.y/objc-parse.y/g -s/$(srcdir)\/c-gperf/c-gperf/g -/^multilib.h/ s/multilib/not-multilib/ -/^xmake_file=/ d -/^tmake_file=/ d -/^lang_specs_files=/ d -/^lang_options_files=/ d -/^version=/ c\ -version=2.7.2.1 -s/CC = cc/CC = cl/ -s/^SHELL =.*/SHELL =/ -s/CFLAGS = -g/CFLAGS =/ -s/:\$/: \$/g -s/<\ *\$(srcdir)\//< $(srcdir)\\/g -s/^ \$(srcdir)\/move-if-change/ copy/ -s/^USE_/# USE_/ -s/`echo \$(srcdir)\///g -s/ | sed 's,\^\\\.\/,,'`//g -s/^ cd \$(srcdir)[ ]*;/ / -/^stamp-attrtab/,/copy/ { - /\\$/d - / fi/d - /copy/ i\ -\ genattrtab $(md_file) > tmp-attrtab.c -} -/^enquire[ ]*:/ s/\$(GCC_PARTS)//g -/^enquire.o[ ]*:/ s/\$(GCC_PASSES)//g -/^GCC_FOR_TARGET =/ c\ -GCC_FOR_TARGET = xgcc -/^ENQUIRE_LDFLAGS =/ c\ -ENQUIRE_LDFLAGS = -s/; *@true// -/> *stamp-objlist/ c\ - echo.exe $(OBJS) $(BC_OBJS) | sed -e "s, \([a-z]\), ../\1,g" >stamp-objlist -/^OBJS.*stamp-objlist/ s?`cat ../stamp-objlist`?@../stamp-objlist? -s/^\(SUBDIR_OBSTACK *=\).*$/\1 ..\/obstack.o/ -s/^\(SUBDIR_USE_ALLOCA *=\).*$/\1/ -s/^\(SUBDIR_MALLOC *=\).*$/\1/ -/####target/ i\ -STMP_FIXPROTO = \ -OTHER_FIXINCLUDES_DIRS=. \ -RANLIB = : \ -RANLIB_TEST = false \ -OLDCC = cl \ -MAKE = nmake \ -SYMLINK = copy \ -INSTALL = $(srcdir)/install.sh -c \ -exeext = .exe \ -objext = .obj \ -oldobjext = .obj \ -\ -EXTRA_PROGRAMS=ld.exe \ -\ -ld.obj: $(srcdir)/config/winnt/ld.c \ -\ $(CC) $(CFLAGS) \\\ -\ -I. -I$(srcdir) -I$(srcdir)/config -c $(srcdir)/config/winnt/ld.c \ -\ -ld.exe: ld.obj \ - link -out:ld.exe ld.obj $(LDFLAGS) $(CLIB) \ -\ -EXTRA_GCC_OBJS=spawnv.obj oldnames.obj \ -spawnv.obj: $(srcdir)/config/winnt/spawnv.c \ -\ $(CC) $(CFLAGS) \\\ -\ -I. -I$(srcdir) -I$(srcdir)/config -c $(srcdir)/config/winnt/spawnv.c \ -\ -oldnames.obj: $(srcdir)/config/winnt/oldnames.c \ -\ $(CC) $(CFLAGS) \\\ -\ -I. -I$(srcdir) -I$(srcdir)/config -c $(srcdir)/config/winnt/oldnames.c -s/^C c:/Cc:/ -s/\${OBJS}/\$(OBJS)/g -s/\${SYSTEM_HEADER_DIR}/\$(SYSTEM_HEADER_DIR)/g -s/\${HOST_CC}/\$(HOST_CC)/g -s/ \${srcdir}\// /g -s/\${mainversion}/\$(mainversion)/g -s/\ $(srcdir)\/move-if-change$// -s/\$(srcdir)\/move-if-change/copy/g -/^# USE_HOST_OBSTACK/ i\ -USE_HOST_OBSTACK=obstack.obj -/^# USE_ALLOCA/ i\ -USE_ALLOCA=alloca.obj -/^# USE_HOST_ALLOCA/ i\ -USE_HOST_ALLOCA=alloca.obj -s/^ALLOCA =/ALLOCA = alloca.obj/ -s/^ALLOCA_FINISH = true/ALLOCA_FINISH =/ -s/ \.\// / -s/^bi-\([a-z]*\) *:/bi-\1.exe :/ -s/ bi-\([a-z]*\)$/ bi-\1.exe/ -s/ bi-\([a-z]*\) / bi-\1.exe /g -s/^gen\([a-z]*\) *:/gen\1.exe :/ -s/ gen\([a-z]*\)$/ gen\1.exe/ -s/ gen\([a-z]*\) / gen\1.exe /g -s/genmultilib.exe/genmultilib/g -s/^cccp *:/cccp.exe :/ -s/cccp$/cccp.exe/ -s/cccp /cccp.exe / -s/CCCP=cccp.exe/CCCP=cccp/ -s/(CCCP)$/(CCCP)$(exeext)/ -s/^cpp *:/cpp.exe :/ -s/cpp$/cpp.exe/ -s/cpp /cpp.exe / -s/^cc1 *:/cc1.exe :/ -s/cc1$/cc1.exe/ -s/cc1 /cc1.exe / -s/^cc1obj *:/cc1obj.exe :/ -s/cc1obj$/cc1obj.exe/ -s/cc1obj /cc1obj.exe / -s/^xgcc *:/xgcc.exe :/ -s/xgcc$/xgcc.exe/ -s/xgcc /xgcc.exe / -s/^enquire *:/enquire.exe :/ -s/enquire$/enquire.exe/ -s/enquire /enquire.exe / -s/\.o *:/.obj :/ -s/\.o$/.obj/ -s/\.o /.obj /g -s/-rm -f cpp.exe/del cpp.exe/ -s/\$(CC) \$(ALL_CFLAGS) \$(LDFLAGS) -o /link $(LDFLAGS) -out:/ -s/\$(HOST_CC) \$(HOST_CFLAGS) \$(HOST_LDFLAGS) -o /link $(HOST_LDFLAGS) -out:/ -/^# Build libgcc.a/ r config/winnt/libgcc.mak -/^# Build libgcc.a/,/ / d -/^# Build the include directory\./ r config/winnt/headers.mak -/^# Build the include directory\./,/touch objc-headers/ d -s/^\ // diff --git a/support/cpp/winnt/config.h b/support/cpp/winnt/config.h deleted file mode 100644 index 2f7d731d..00000000 --- a/support/cpp/winnt/config.h +++ /dev/null @@ -1 +0,0 @@ -#include "/xm-winnt.h" diff --git a/support/cpp/winnt/dirent.c b/support/cpp/winnt/dirent.c deleted file mode 100644 index 59f7dc1c..00000000 --- a/support/cpp/winnt/dirent.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * @(#)msd_dir.c 1.4 87/11/06 Public Domain. - * - * A public domain implementation of BSD directory routines for - * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), - * August 1897 - * - * Modified by Ian Stewartson, Data Logic (istewart@datlog.co.uk). - * - * Updates: 1. To support OS/2 1.x - * 2. To support HPFS long filenames - * 3. To support OS/2 2.x - * 4. To support TurboC - * 5. To support Windows NT - */ - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - - -#define WIN32_LEAN_AND_MEAN -#include - -#define FILE_NAME_E cFileName -#define OS_CloseFH(a) FindClose (a) -#define FIND_BUFFER WIN32_FIND_DATA -#define DISABLE_HARD_ERRORS SetErrorMode (0) -#define ENABLE_HARD_ERRORS SetErrorMode (SEM_FAILCRITICALERRORS | \ - SEM_NOOPENFILEERRORBOX); - -# define ERROR_EMPTY_DIR ERROR_FILE_NOT_FOUND - -# define ATTRIBUTES (_A_SUBDIR | _A_HIDDEN | _A_SYSTEM | \ - _A_NORMAL | _A_RDONLY | _A_ARCH) - -/* - * missing ?? - */ - -#ifndef ENOTDIR -# define ENOTDIR 120 /* Not a directory */ -#endif - -#ifndef S_IFMT -# define S_IFMT 0xf000 /* type of file */ -#endif - -#ifndef S_ISDIR -# define S_ISDIR(m) ((((m) & S_IFMT) == S_IFDIR)) -#endif - -/* - * Internals - */ - -typedef struct _dircontents DIRCONT; -static void free_dircontents (DIRCONT *); - -/* - * Open the directory stream - */ - -DIR * -opendir (name) - const char *name; -{ - struct stat statb; - DIR *dirp; - char *last; - DIRCONT *dp; - char *nbuf; - int len = strlen (name); - unsigned long rc; - FIND_BUFFER dtabuf; - HANDLE d_handle; - bool HPFS = FALSE; - - if (!len) - { - errno = ENOTDIR; - return (DIR *)NULL; - } - - if ((nbuf = malloc (len + 5)) == (char *)NULL) - return (DIR *) NULL; - - strcpy (nbuf, name); - last = &nbuf[len - 1]; - -/* Ok, DOS is very picky about its directory names. The following are - * valid. - * - * c:/ - * c:. - * c:name/name1 - * - * c:name/ is not valid - */ - - if (((*last == '\\') || (*last == '/')) && (len > 1) && - (!((len == 3) && (name[1] == ':')))) - *(last--) = 0; - -/* Check its a directory */ - - DISABLE_HARD_ERRORS; - rc = stat (nbuf, &statb); - ENABLE_HARD_ERRORS; - - if (rc) - { - free (nbuf); - return (DIR *) NULL; - } - - if (!S_ISDIR (statb.st_mode)) - { - free (nbuf); - errno = ENOTDIR; - return (DIR *)NULL; - } - - if ((dirp = (DIR *) malloc (sizeof (DIR))) == (DIR *) NULL) - { - free (nbuf); - return (DIR *) NULL; - } - -/* Set up to find everything */ - - if ((*last != '\\') && (*last != '/')) - strcat (last, "/"); - - strcat (last, "*.*"); - -/* Find the file system type */ - - HPFS = IsHPFSFileSystem (nbuf); - - dirp->dd_loc = 0; - dirp->dd_cp = (DIRCONT *) NULL; - dirp->dd_contents = (DIRCONT *) NULL; - - DISABLE_HARD_ERRORS; - - d_handle = FindFirstFile (nbuf, &dtabuf); - rc = (d_handle == INVALID_HANDLE_VALUE) ? GetLastError () : 0; - - ENABLE_HARD_ERRORS; - -/* Check for errors */ - - if (rc) - { - free (nbuf); - -/* Empty directory */ - -#if defined (ERROR_EMPTY_DIR) - if (rc == ERROR_EMPTY_DIR) - return dirp; -#endif - - free (dirp); - return (DIR *) NULL; - } - -/* Process the directory */ - - do - { - if (((dp = (DIRCONT *) malloc (sizeof (DIRCONT))) == (DIRCONT *)NULL) || - ((dp->_d_entry = strdup (dtabuf.FILE_NAME_E)) == (char *) NULL)) - { - if (dp->_d_entry != (char *)NULL) - free ((char *)dp); - - free (nbuf); - free_dircontents (dirp->dd_contents); - - OS_CloseFH (d_handle); - return (DIR *) NULL; - } - - if (!HPFS) - strlwr (dp->_d_entry); - - if (dirp->dd_contents != (DIRCONT *) NULL) - dirp->dd_cp = dirp->dd_cp->_d_next = dp; - - else - dirp->dd_contents = dirp->dd_cp = dp; - - dp->_d_next = (DIRCONT *) NULL; - - } while (FindNextFile (d_handle, &dtabuf)); - - dirp->dd_cp = dirp->dd_contents; - free (nbuf); - - OS_CloseFH (d_handle); - return dirp; -} - - -/* - * Close the directory stream - */ - -int -closedir (dirp) - DIR *dirp; -{ - if (dirp != (DIR *)NULL) - { - free_dircontents (dirp->dd_contents); - free ((char *)dirp); - } - - return 0; -} - -/* - * Read the next record from the stream - */ - -struct dirent * -readdir (dirp) - DIR *dirp; -{ - static struct dirent dp; - - if ((dirp == (DIR *)NULL) || (dirp->dd_cp == (DIRCONT *) NULL)) - return (struct dirent *) NULL; - - dp.d_reclen = strlen (strcpy (dp.d_name, dirp->dd_cp->_d_entry)); - dp.d_off = dirp->dd_loc * 32; - dp.d_ino = (ino_t)++dirp->dd_loc; - dirp->dd_cp = dirp->dd_cp->_d_next; - - return &dp; -} - -/* - * Restart the directory stream - */ - -void -rewinddir (dirp) - DIR *dirp; -{ - seekdir (dirp, (off_t)0); -} - -/* - * Move to a know position in the stream - */ - -void -seekdir (dirp, off) - DIR *dirp; - off_t off; -{ - long i = off; - DIRCONT *dp; - - if ((dirp == (DIR *)NULL) || (off < 0L)) - return; - - for (dp = dirp->dd_contents; (--i >= 0) && (dp != (DIRCONT *)NULL); - dp = dp->_d_next) - ; - - dirp->dd_loc = off - (i + 1); - dirp->dd_cp = dp; -} - -/* - * Get the current position - */ - -off_t -telldir(dirp) - DIR *dirp; -{ - return (dirp == (DIR *)NULL) ? (off_t) -1 : dirp->dd_loc; -} - -/* - * Release the internal structure - */ - -static void -free_dircontents (dp) - DIRCONT *dp; -{ - DIRCONT *odp; - - while ((odp = dp) != (DIRCONT *)NULL) - { - if (dp->_d_entry != (char *)NULL) - free (dp->_d_entry); - - dp = dp->_d_next; - free ((char *)odp); - } -} - - -/* - * Windows NT version - */ - -bool -IsHPFSFileSystem (directory) - char *directory; -{ - char bName[4]; - DWORD flags; - DWORD maxname; - BOOL rc; - unsigned int nDrive; - char szCurDir [MAX_PATH]; - - if (isalpha (directory[0]) && (directory[1] == ':')) - nDrive = toupper (directory[0]) - '@'; - - else - { - GetCurrentDirectory (MAX_PATH, szCurDir); - nDrive = szCurDir[0] - 'A' + 1; - } - -/* Set up the drive name */ - - strcpy (bName, "x:\\"); - bName[0] = (char) (nDrive + '@'); - -/* Read the volume info, if we fail - assume non-HPFS */ - - DISABLE_HARD_ERRORS; - - rc = GetVolumeInformation (bName, (LPTSTR)NULL, 0, (LPDWORD)NULL, - &maxname, &flags, (LPTSTR)NULL, 0); - ENABLE_HARD_ERRORS; - - return ((rc) && (flags & (FS_CASE_SENSITIVE | FS_CASE_IS_PRESERVED))) - ? TRUE : FALSE; -} - diff --git a/support/cpp/winnt/dirent.h b/support/cpp/winnt/dirent.h deleted file mode 100644 index 822bd2ca..00000000 --- a/support/cpp/winnt/dirent.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * dirent.h - */ - -#ifndef _DIRENT_H -# define _DIRENT_H - -# include -# include - -#define MAXNAMLEN 255 /* maximum filename length */ - -#ifndef NAME_MAX -#define NAME_MAX (MAXNAMLEN - 1) -#endif - -struct dirent /* data from getdents()/readdir() */ -{ - ino_t d_ino; /* inode number of entry */ - off_t d_off; /* offset of disk directory entry */ - wchar_t d_reclen; /* length of this record */ - char d_name[MAXNAMLEN + 1]; -}; - - -/* The following nonportable ugliness could have been avoided by defining - * DIRENTSIZ and DIRENTBASESIZ to also have (struct dirent *) arguments. - * There shouldn't be any problem if you avoid using the DIRENTSIZ() macro. - */ - -#define DIRENTBASESIZ (((struct dirent *)0)->d_name \ - - (char *)&((struct dirent *)0)->d_ino) - -#define DIRENTSIZ(namlen) ((DIRENTBASESIZ + sizeof(long) + (namlen)) \ - / sizeof(long) * sizeof(long)) - - - -# ifndef _BOOL_T_DEFINED -typedef unsigned char bool; -# define _BOOL_T_DEFINED -# endif - -# define DIRBUF 8192 /* buffer size for fs-indep. dirs */ - /* must in general be larger than the */ - /* filesystem buffer size */ - -struct _dircontents { - char *_d_entry; - struct _dircontents *_d_next; -}; - -typedef struct _dirdesc { - int dd_id; /* uniquely identify each open directory */ - long dd_loc; /* where we are in directory entry is this */ - struct _dircontents *dd_contents; /* pointer to contents of dir */ - struct _dircontents *dd_cp; /* pointer to current position */ -} DIR; - - -#if defined (__STDC__) -# define _PROTO(p) p -#else -# define _PROTO(p) () -# undef const -# undef volatile -#endif - -/* Functions */ - -extern DIR * opendir _PROTO ((const char *)); -extern struct dirent * readdir _PROTO ((DIR *)); -extern void rewinddir _PROTO ((DIR *)); - -extern int closedir _PROTO ((DIR *)); -extern void seekdir _PROTO ((DIR *, off_t)); -extern off_t telldir _PROTO ((DIR *)); - -extern int chdir _PROTO ((const char *)); -extern char * getcwd _PROTO ((char *, size_t)); - -extern int mkdir _PROTO ((const char *)); - -extern int rmdir _PROTO ((const char *)); -extern int scandir _PROTO ((char *, - struct dirent ***, - int (*)(const void *, const void *), - int (*)(const void *, const void *))); - -extern int _chdrive _PROTO ((int)); -extern int _getdrive _PROTO ((void)); -extern char * _getdcwd _PROTO ((int, char *, int)); - -extern bool IsHPFSFileSystem _PROTO ((char *)); - -#endif diff --git a/support/cpp/winnt/fixinc-nt.c b/support/cpp/winnt/fixinc-nt.c deleted file mode 100644 index f49d6dda..00000000 --- a/support/cpp/winnt/fixinc-nt.c +++ /dev/null @@ -1,260 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -static char *concat(); -static char *concat3(); -static char *concat4(); -static int onlyonedir; -static int atleastone; -static char *fixeddirs, *origdirs; - -/* Convert all /'s to \'s */ - -char * -slash2slash (dirname) - char *dirname; -{ - int i; - for (i=0; dirname[i]; i++) - if (dirname [i] == '/') - dirname [i] = '\\'; - - return dirname; -} - -/* Examine each directory component of a path and create the directory */ - -int -mkdirpath (dirpath) - char *dirpath; -{ - char *ndirpath = strdup (dirpath); - char *bp, *fp; - - fp = bp = ndirpath; - - while (bp) - { - bp = strchr (fp, '\\'); - if (bp) - { - *bp = 0; - _mkdir (ndirpath); - *bp = '\\'; - fp = ++bp; - } - else - _mkdir (ndirpath); - } -} - -/* Construct a relative directory path from a given path by removing the - leading slash, if it exists and changing a drive letter from X: to X-. */ - -char * -newname (olddirname) - char *olddirname; -{ - char *newname = strdup (olddirname); - - if ((strlen (newname) >= 2) - && (isalpha (newname[0]) && newname[1] == ':')) - newname [1] = '-'; - else if ((strlen (newname) >= 1) - && (newname [0] == '/' || newname [0] == '\\')) - newname = &newname[1]; - - return newname; - -} - -/* Run the sed script on one header file. If no modifications were made, then - delete the newly created file. */ - -int -doheader (oneheader, outheader, oldsize) - char *oneheader, *outheader; - int oldsize; -{ - char *newbuff, *oldbuff; - char *newheader = concat3 ("include", "\\", newname (outheader)); - struct _stat newstatbuf; - int newdesc, olddesc; - int i; - - system (concat4 ("sed -f fixinc-nt.sed ", oneheader, " > ", newheader)); - _stat (newheader, &newstatbuf); - if (oldsize != newstatbuf.st_size) - { - atleastone = 1; - printf ("Fixing: %s\n", oneheader); - return 0; - } - oldbuff = malloc (oldsize); - newbuff = malloc (newstatbuf.st_size); - olddesc = open (oneheader, _O_RDONLY | _O_BINARY); - newdesc = open (newheader, _O_RDONLY | _O_BINARY); - read (olddesc, oldbuff, oldsize); - read (newdesc, newbuff, newstatbuf.st_size); - close (olddesc); - close (newdesc); - for (i=0; id_name[0] == '.') - continue; - - intempbuf = slash2slash (concat3 (indir, "\\", dire->d_name)); - outtempbuf = slash2slash (concat3 (outdir, "\\", dire->d_name)); - _stat (intempbuf, &statbuf); - - /* If directory ... */ - if (statbuf.st_mode & _S_IFDIR) - dodir (intempbuf, outtempbuf); - - /* If regular file ... */ - if (statbuf.st_mode & _S_IFREG) - doheader (intempbuf, outtempbuf, statbuf.st_size); - } - closedir (dir); - return 0; -} - -/* Retrieve the value of the Include environment variable, copy it into a - temporary and append a semi-colon for book-keeping purposes. Then call - dodir () for each complete directory that is named therein. If there is - only one directory, then direct the output to use include\. as the - root instead of include/, where is a path - constructed from the path named in the Include environment variable. - I.e. if Include=C:\MSTOOLS\Include;D:\MSVC20\Include then the modified - header files will be in include\C-\MSTOOLS\Include and - include\D-\MSVC20\Include. However if Include=C:\MSTOOLS\Include then the - modified files will be in include\. */ - -int -main () -{ - char *fp, *bp, *foobar; - char *incvar = getenv ("Include"); - int varlen = 0; - struct _stat statbuf; - - if (incvar == NULL) return 0; - - varlen = strlen (incvar); - foobar = (char *) malloc (varlen + 2); - - strcpy (foobar, incvar); - foobar = slash2slash (foobar); - if (foobar [varlen-1] != ';') strcat (foobar, ";"); - fp = bp = foobar; - - if (strchr (fp, ';') == strrchr (fp, ';')) - onlyonedir = 1; - else - onlyonedir = 0; - - fixeddirs = strdup(".\\include"); - origdirs = strdup(""); - - while (bp) - { - bp = strchr (fp, ';'); - if (bp) - { - *bp = 0; - _stat (fp, &statbuf); - if (statbuf.st_mode & _S_IFDIR) - { - atleastone = 0; - if (onlyonedir) - dodir (fp, "."); - else - dodir (fp, fp); - if (atleastone && !onlyonedir) - { - origdirs = concat3 (origdirs, ";", fp); - fixeddirs = concat3 (fixeddirs, ";", - concat3 (".\\include", "\\", newname(fp))); - } - } - fp = ++bp; - } - } - printf ("set C_Include_Path=%s%s\n", fixeddirs, origdirs); - return 0; -} - -/* Utility function that mallocs space and concatenates two strings. */ - -static char * -concat (s1, s2) - char *s1, *s2; -{ - int len1 = strlen (s1); - int len2 = strlen (s2); - char *result = malloc (len1 + len2 + 1); - - strcpy (result, s1); - strcpy (result + len1, s2); - *(result + len1 + len2) = 0; - - return result; -} - -/* Utility function that concatenates three strings. */ - -static char * -concat3 (s1, s2, s3) - char *s1, *s2, *s3; -{ - return concat (concat (s1, s2), s3); -} - -/* Utility function that concatenates four strings. */ - -static char * -concat4 (s1, s2, s3, s4) - char *s1, *s2, *s3, *s4; -{ - return concat (concat (s1, s2), concat (s3, s4)); -} diff --git a/support/cpp/winnt/hconfig.h b/support/cpp/winnt/hconfig.h deleted file mode 100644 index 2f7d731d..00000000 --- a/support/cpp/winnt/hconfig.h +++ /dev/null @@ -1 +0,0 @@ -#include "/xm-winnt.h" diff --git a/support/cpp/winnt/headers.mak b/support/cpp/winnt/headers.mak deleted file mode 100644 index 8dec3413..00000000 --- a/support/cpp/winnt/headers.mak +++ /dev/null @@ -1,51 +0,0 @@ -# Build the include directory. The stamp files are stmp-* rather than -# stamp-* so that mostlyclean does not force the include directory to -# be rebuilt. - - -# Copy in the headers provided with gcc. -USER_H = $(srcdir)\ginclude\stdarg.h $(srcdir)\ginclude\stddef.h \ - $(srcdir)\ginclude\varargs.h $(srcdir)\ginclude\va-alpha.h \ - $(srcdir)\ginclude\va-h8300.h $(srcdir)\ginclude\va-i860.h \ - $(srcdir)\ginclude\va-i960.h $(srcdir)\ginclude\va-mips.h \ - $(srcdir)\ginclude\va-m88k.h $(srcdir)\ginclude\va-pa.h \ - $(srcdir)\ginclude\va-pyr.h $(srcdir)\ginclude\va-sparc.h \ - $(srcdir)\ginclude\va-clipper.h $(srcdir)\ginclude\va-spur.h \ - $(srcdir)\ginclude\iso646.h \ - $(srcdir)\ginclude\proto.h - -# Build the include directory except for float.h (which depends upon -# enquire). - -stmp-int-hdrs: $(USER_H) - type $(srcdir)\limitx.h >xlimits.h - type $(srcdir)\glimits.h >>xlimits.h - type $(srcdir)\limity.h >>xlimits.h - - -mkdir include - for %%f in ($(USER_H)) do copy %%f include - del include\limits.h - copy xlimits.h include\limits.h - del include\syslimits.h - copy $(srcdir)\gsyslimits.h include\syslimits.h - copy include\limits.h include\syslimits.h - del include\README - copy $(srcdir)\README-fixinc include\README - touch stmp-int-hdrs - -stmp-headers: stmp-int-hdrs fixinc-nt.exe - fixinc-nt - touch stmp-headers - -# Build float.h. -stmp-float_h: libgcc.lib enquire.exe - -.\enquire -f > tmp-float.h - del include\float.h - copy tmp-float.h include\float.h - touch stmp-float_h - -fixinc-nt.obj: $(srcdir)/config/winnt/fixinc-nt.c - cl -c -I. -I$(srcdir) -I$(srcdir)/include -I$(srcdir)/config/winnt $(srcdir)/config/winnt/fixinc-nt.c - -fixinc-nt.exe: fixinc-nt.obj dirent.obj - cl fixinc-nt.obj dirent.obj libc.lib kernel32.lib diff --git a/support/cpp/winnt/ld.c b/support/cpp/winnt/ld.c deleted file mode 100644 index 67d53e78..00000000 --- a/support/cpp/winnt/ld.c +++ /dev/null @@ -1,348 +0,0 @@ -/* Call Windows NT 3.x linker. - Copyright (C) 1994, 1995 Free Software Foundation, Inc. - Contributed by Douglas B. Rupp (drupp@cs.washington.edu). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config.h" -#include -#include -#include -#include -#include -#include - -static char *concat (); -static char *concat3 (); - -/* These can be set by command line arguments */ -char *linker_path = 0; -int verbose = 0; -int subsystem = 0; -int entry = 0; - -int link_arg_max = -1; -char **link_args = (char **) 0; -int link_arg_index = -1; - -char *search_dirs = "."; - -static int is_regular_file (char *name); - -/* Add the argument contained in STR to the list of arguments to pass to the - linker */ - -static void -addarg (str) - char *str; -{ - int i; - - if (++link_arg_index >= link_arg_max) - { - char **new_link_args - = (char **) calloc (link_arg_max + 1000, sizeof (char *)); - - for (i = 0; i <= link_arg_max; i++) - new_link_args [i] = link_args [i]; - - if (link_args) - free (link_args); - - link_arg_max += 1000; - link_args = new_link_args; - } - - link_args [link_arg_index] = str; -} - -/* Locate the file named in FILE_NAME in the set of paths contained in - PATH_VAL */ - -static char * -locate_file (file_name, path_val) - char *file_name; - char *path_val; -{ - char buf [1000]; - int file_len = strlen (file_name); - char *end_path = path_val + strlen (path_val); - char *ptr; - - /* Handle absolute pathnames */ - if (file_name [0] == '/' || file_name [0] == DIR_SEPARATOR - || isalpha (file_name [0]) && file_name [1] == ':') - { - strncpy (buf, file_name, sizeof buf); - buf[sizeof buf - 1] = '\0'; - if (is_regular_file (buf)) - return strdup (buf); - else - return 0; - } - - if (! path_val) - return 0; - - for (;;) - { - for (; *path_val == PATH_SEPARATOR ; path_val++) - ; - if (! *path_val) - return 0; - - for (ptr = buf; *path_val && *path_val != PATH_SEPARATOR; ) - *ptr++ = *path_val++; - - ptr--; - if (*ptr != '/' && *ptr != DIR_SEPARATOR) - *++ptr = DIR_SEPARATOR; - - strcpy (++ptr, file_name); - - if (is_regular_file (buf)) - return strdup (buf); - } - - return 0; -} - -/* Given a library name in NAME, i.e. foo. Look first for libfoo.lib and then - libfoo.a in the set of directories we are allowed to search in */ - -static char * -expand_lib (name) - char *name; -{ - char *lib, *lib_path; - - lib = malloc (strlen (name) + 8); - strcpy (lib, "lib"); - strcat (lib, name); - strcat (lib, ".lib"); - lib_path = locate_file (lib, search_dirs); - if (!lib_path) - { - strcpy (lib, "lib"); - strcat (lib, name); - strcat (lib, ".a"); - lib_path = locate_file (lib, search_dirs); - if (!lib_path) - { - fprintf - (stderr, - "Couldn't locate library: lib%s.a or lib%s.lib\n", name, name); - exit (1); - } - } - - return lib_path; -} - -/* Check to see if the file named in NAME is a regular file, i.e. not a - directory */ - -static int -is_regular_file (name) - char *name; -{ - int ret; - struct stat statbuf; - - ret = stat(name, &statbuf); - return !ret && S_ISREG (statbuf.st_mode); -} - -/* Process the number of args in P_ARGC and contained in ARGV. Look for - special flags, etc. that must be handled for the Microsoft linker */ - -static void -process_args (p_argc, argv) - int *p_argc; - char *argv[]; -{ - int i, j; - - for (i = 1; i < *p_argc; i++) - { - /* -v turns on verbose option here and is passed on to gcc */ - if (! strcmp (argv [i], "-v")) - verbose = 1; - else if (! strncmp (argv [i], "-g", 2)) - { - addarg ("-debugtype:coff -debug:full"); - } - else if (! strncmp (argv [i], "-stack", 6)) - { - i++; - addarg (concat ("-stack:",argv[i])); - } - else if (! strncmp (argv [i], "-subsystem", 10)) - { - subsystem = 1; - i++; - addarg (concat ("-subsystem:",argv[i])); - } - else if (! strncmp (argv [i], "-e", 2)) - { - entry = 1; - i++; - addarg (concat ("-entry:",&argv[i][1])); - } - } -} - -/* The main program. Spawn the Microsoft linker after fixing up the - Unix-like flags and args to be what the Microsoft linker wants */ - -main (argc, argv) - int argc; - char *argv[]; -{ - int i; - int done_an_ali = 0; - int file_name_index; - char *pathval = getenv ("PATH"); - char *spawn_args [5]; - char *tmppathval = malloc (strlen (pathval) + 3); - - strcpy (tmppathval, ".;"); - pathval = strcat (tmppathval, pathval); - - linker_path = locate_file ("link32.exe", pathval); - if (!linker_path) - { - linker_path = locate_file ("link.exe", pathval); - if (!linker_path) - { - fprintf (stderr, "Couldn't locate link32 or link\n"); - exit (1); - } - } - - addarg (linker_path); - - process_args (&argc , argv); - if (! subsystem) addarg ("-subsystem:console"); - if (! entry) addarg ("-entry:mainCRTStartup"); - - for (i = 1; i < argc; i++) - { - int arg_len = strlen (argv [i]); - - if (!strcmp (argv [i], "-o")) - { - char *buff, *ptr; - int out_len; - - i++; - out_len = strlen (argv[i]) + 10; - buff = malloc (out_len); - strcpy (buff, "-out:"); - strcat (buff, argv[i]); - ptr = strstr (buff, ".exe"); - if (ptr == NULL || strlen (ptr) != 4) - strcat (buff, ".exe"); - addarg (buff); - } - else if (arg_len > 2 && !strncmp (argv [i], "-L", 2)) - { - char *nbuff, *sdbuff; - int j, new_len, search_dirs_len; - - new_len = strlen (&argv[i][2]); - search_dirs_len = strlen (search_dirs); - - nbuff = malloc (new_len + 1); - strcpy (nbuff, &argv[i][2]); - - for (j = 0; j < new_len; j++) - if (nbuff[j] == '/') nbuff[j] = DIR_SEPARATOR; - - sdbuff = malloc (search_dirs_len + new_len + 2); - strcpy (sdbuff, search_dirs); - sdbuff[search_dirs_len] = PATH_SEPARATOR; - sdbuff[search_dirs_len+1] = 0; - strcat (sdbuff, nbuff); - - search_dirs = sdbuff; - } - - else if (arg_len > 2 && !strncmp (argv [i], "-l", 2)) - { - addarg (expand_lib (&argv[i][2])); - } - else if (!strcmp (argv [i], "-v") - || !strcmp (argv [i], "-g") - || !strcmp (argv [i], "-noinhibit-exec")) - { - ; - } - else if (!strcmp (argv [i], "-stack") - || !strcmp (argv [i], "-subsystem") - || !strcmp (argv [i], "-e")) - { - i++; - } - else - { - addarg (argv [i]); - } - } - - addarg (NULL); - - if (verbose) - { - int i; - - for (i = 0; i < link_arg_index; i++) - printf ("%s ", link_args [i]); - putchar ('\n'); - } - - if (spawnvp (P_WAIT, linker_path, (const char * const *)link_args) != 0) - { - fprintf (stderr, "Error executing %s\n", link_args[0]); - exit (1); - } - - exit (0); -} - -static char * -concat (s1, s2) - char *s1, *s2; -{ - int len1 = strlen (s1); - int len2 = strlen (s2); - char *result = malloc (len1 + len2 + 1); - - strcpy (result, s1); - strcpy (result + len1, s2); - *(result + len1 + len2) = 0; - - return result; -} - -static char * -concat3 (s1, s2, s3) - char *s1, *s2, *s3; -{ - return concat (concat (s1, s2), s3); -} diff --git a/support/cpp/winnt/libgcc.mak b/support/cpp/winnt/libgcc.mak deleted file mode 100644 index adfb57e6..00000000 --- a/support/cpp/winnt/libgcc.mak +++ /dev/null @@ -1,19 +0,0 @@ -# Build libgcc.a - -libgcc.lib : libgcc1.c libgcc2.c mklibgcc.exe - mklibgcc -c - mklibgcc "cl -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES)" libgcc1.c $(LIB1FUNCS) - mklibgcc "xgcc -B./ -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES)" libgcc2.c $(LIB2FUNCS) - mklibnow.bat - -del libgcc.lib - lib -verbose -out:libgcc.lib lgcctmp/*.obj - -mklibgcc.obj : $(srcdir)/config/winnt/mklibgcc.c - cl -I. -I$(srcdir) -I$(srcdir)/config/winnt -c $(srcdir)/config/winnt/mklibgcc.c - -dirent.obj : $(srcdir)/config/winnt/dirent.c stmp-int-hdrs - cl -I. -I$(srcdir) -I$(srcdir)/include -I$(srcdir)/config/winnt -c $(srcdir)/config/winnt/dirent.c - -mklibgcc.exe : mklibgcc.obj dirent.obj - cl mklibgcc.obj dirent.obj libc.lib kernel32.lib - diff --git a/support/cpp/winnt/mklibgcc.c b/support/cpp/winnt/mklibgcc.c deleted file mode 100644 index 081e4ec2..00000000 --- a/support/cpp/winnt/mklibgcc.c +++ /dev/null @@ -1,97 +0,0 @@ -#include -#include -#include - -char *skips[] = { - 0 -}; - -int -do_clean() -{ - DIR *dir; - struct dirent *de; - remove("mklibnow.bat"); - - dir = opendir("lgcctmp"); - if (!dir) - return 0; - while ((de=readdir(dir))) - { - char buf[30]; - if (de->d_name[0] == '.') - continue; - sprintf(buf, "lgcctmp/%s", de->d_name); - unlink(buf); - } - closedir(dir); - return 0; -} - -int -main(int argc, char **argv) -{ - char *cc = argv[1]; - char *csrc=argv[2]; - int i; - FILE *batfile; - FILE *cfile; - - if (argc > 1 && strcmp(argv[1], "-c")==0) - return do_clean(); - - _mkdir("lgcctmp", 0755); - - batfile = fopen("mklibnow.bat", "a"); - if (!batfile) - { - perror("mklibnow.bat"); - return 1; - } -/* fprintf(batfile, "@echo off\n"); */ - - for (i=3; i - -#ifndef USG -#define USG 1 -#endif - -#ifndef ONLY_INT_FIELD -#define ONLY_INT_FIELDS 1 -#endif - -#ifndef USE_PROTOTYPES -#define USE_PROTOTYPES 1 -#endif - -#ifndef HAVE_PUTENV -#define HAVE_PUTENV 1 -#endif - -#ifndef HAVE_VPRINTF -#define HAVE_VPRINTF 1 -#endif - -#define NO_SYS_SIGLIST 1 -#define bcmp(a,b,c) memcmp (a,b,c) -#define bcopy(a,b,c) memcpy (b,a,c) -#define bzero(a,b) memset (a,0,b) -#define index strchr -#define rindex strrchr -#define kill(a,b) raise(b) - -#define OBJECT_SUFFIX ".obj" -#define EXECUTABLE_SUFFIX ".exe" -#define PATH_SEPARATOR ';' -#define DIR_SEPARATOR '\\' - -#define S_IRUSR 0000400 -#define S_IWUSR 0000200 -#define S_IXUSR 0000100 -#define S_IRGRP 0000040 -#define S_IWGRP 0000020 -#define S_IXGRP 0000010 -#define S_IROTH 0000004 -#define S_IWOTH 0000002 -#define S_IXOTH 0000001 -#define S_IRWXU S_IRUSR | S_IWUSR | S_IXUSR -#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) -#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) - diff --git a/support/cpp/winnt/win-nt.h b/support/cpp/winnt/win-nt.h deleted file mode 100644 index 4b93f8c1..00000000 --- a/support/cpp/winnt/win-nt.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Operating system specific defines to be used when targeting GCC for - Windows NT 3.x. - Copyright (C) 1994, 1995 Free Software Foundation, Inc. - Contributed by Douglas B. Rupp (drupp@cs.washington.edu). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define TARGET_MEM_FUNCTIONS - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "" - -#undef LINK_SPEC -#define LINK_SPEC "-stack 5000000,5000000 -noinhibit-exec %{g}" - -#undef CPP_SPEC -#define CPP_SPEC "-lang-c-c++-comments" - -#undef STANDARD_EXEC_PREFIX -#define STANDARD_EXEC_PREFIX "" - -#undef STANDARD_STARTFILE_PREFIX -#define STANDARD_STARTFILE_PREFIX "" - -#undef TOOLDIR_BASE_PREFIX -#define TOOLDIR_BASE_PREFIX "" - -#ifdef STANDARD_INCLUDE_DIR -#undef STANDARD_INCLUDE_DIR -#endif -#define STANDARD_INCLUDE_DIR "" - -#undef LOCAL_INCLUDE_DIR -#define LOCAL_INCLUDE_DIR "" - -#undef INCLUDE_DEFAULTS -#define INCLUDE_DEFAULTS \ - { \ - { 0, 0, 0 } \ - } - -#undef STDC_VALUE -#define STDC_VALUE 0 diff --git a/support/cpp/winnt/x-winnt b/support/cpp/winnt/x-winnt deleted file mode 100644 index 36e36b9c..00000000 --- a/support/cpp/winnt/x-winnt +++ /dev/null @@ -1,34 +0,0 @@ -STMP_FIXPROTO = -OTHER_FIXINCLUDES_DIRS=${srcdir} -RANLIB = : -RANLIB_TEST = false -OLDCC = cl -MAKE = make -SHELL = sh -SYMLINK = cp -INSTALL = $(srcdir)/install.sh -c -.SUFFIXES: .obj -.c.obj: - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< -.adb.obj: - $(CC) -c $(ALL_ADAFLAGS) $< -.ads.obj: - $(CC) -c $(ALL_ADAFLAGS) $< -exeext = .exe -objext = .obj - -CC = gcc -CLIB = -LDFLAGS = - -ld.o: $(srcdir)/config/winnt/ld.c - $(CC) -I. -I$(srcdir) -I$(srcdir)/config -c $(srcdir)/config/winnt/ld.c - -ld.exe: ld.o - $(CC) -o ld.exe ld.o - -oldnames.o: $(srcdir)/config/winnt/oldnames.c - $(CC) -I. -I$(srcdir) -I$(srcdir)/config -c $(srcdir)/config/winnt/oldnames.c - -spawnv.o: $(srcdir)/config/winnt/spawnv.c - $(CC) -I. -I$(srcdir) -I$(srcdir)/config -c $(srcdir)/config/winnt/spawnv.c diff --git a/support/cpp/winnt/xm-winnt.h b/support/cpp/winnt/xm-winnt.h deleted file mode 100644 index be62d020..00000000 --- a/support/cpp/winnt/xm-winnt.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Configuration for GNU compiler for processor running Windows NT 3.x. - Copyright (C) 1993, 1995 Free Software Foundation, Inc. - Contributed by Douglas B. Rupp (drupp@cs.washington.edu) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include - -#ifndef USG -#define USG 1 -#endif - -#ifndef ONLY_INT_FIELD -#define ONLY_INT_FIELDS 1 -#endif - -#ifndef USE_PROTOTYPES -#define USE_PROTOTYPES 1 -#endif - -#ifndef HAVE_PUTENV -#define HAVE_PUTENV 1 -#endif - -#ifndef HAVE_VPRINTF -#define HAVE_VPRINTF 1 -#endif - -#define NO_SYS_SIGLIST 1 -#define bcmp(a,b,c) memcmp (a,b,c) -#define bcopy(a,b,c) memcpy (b,a,c) -#define bzero(a,b) memset (a,0,b) -#define index strchr -#define rindex strrchr -#define kill(a,b) raise(b) - -#define OBJECT_SUFFIX ".obj" -#define EXECUTABLE_SUFFIX ".exe" -#define PATH_SEPARATOR ';' -#define DIR_SEPARATOR '\\' - -#define S_IRUSR 0000400 -#define S_IWUSR 0000200 -#define S_IXUSR 0000100 -#define S_IRGRP 0000040 -#define S_IWGRP 0000020 -#define S_IXGRP 0000010 -#define S_IROTH 0000004 -#define S_IWOTH 0000002 -#define S_IXOTH 0000001 -#define S_IRWXU S_IRUSR | S_IWUSR | S_IXUSR -#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) -#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) -