+++ /dev/null
-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
+++ /dev/null
-#
-#
-#
-
-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
+++ /dev/null
-
-
-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}
-
+++ /dev/null
-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
+++ /dev/null
-#
-# Makefile targets to remake configuration
-#
-
-freshconf: Makefile
-
-Makefile: $(srcdir)/Makefile.in $(PRJDIR)/configure.in
- cd $(PRJDIR) && $(SHELL) ./config.status
-
-# End of conf.mk
+++ /dev/null
-#if defined(_MSC_VER)
-
-#include <stdlib.h>
-#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 <string.h>
-#include <stdlib.h>
-#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
+++ /dev/null
-.so man1/cccp.1
+++ /dev/null
-'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}{}
+++ /dev/null
-\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}
+++ /dev/null
-\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}
+++ /dev/null
-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.
-
-\1f
-Indirect:
-cpp.info-1: 798
-cpp.info-2: 50204
-cpp.info-3: 90189
-\1f
-Tag Table:
-(Indirect)
-Node: Top\7f798
-Node: Global Actions\7f3370
-Node: Directives\7f5890
-Node: Header Files\7f7577
-Node: Header Uses\7f8236
-Node: Include Syntax\7f9728
-Node: Include Operation\7f12870
-Node: Once-Only\7f14732
-Node: Inheritance\7f17157
-Node: Macros\7f19719
-Node: Simple Macros\7f20633
-Node: Argument Macros\7f23621
-Node: Predefined\7f29419
-Node: Standard Predefined\7f29849
-Node: Nonstandard Predefined\7f36986
-Node: Stringification\7f40562
-Node: Concatenation\7f43488
-Node: Undefining\7f46761
-Node: Redefining\7f47800
-Node: Macro Pitfalls\7f49100
-Node: Misnesting\7f50204
-Node: Macro Parentheses\7f51218
-Node: Swallow Semicolon\7f53095
-Node: Side Effects\7f54995
-Node: Self-Reference\7f56693
-Node: Argument Prescan\7f58969
-Node: Cascaded Macros\7f63971
-Node: Newlines in Args\7f65116
-Node: Conditionals\7f66461
-Node: Conditional Uses\7f67813
-Node: Conditional Syntax\7f69236
-Node: #if Directive\7f69822
-Node: #else Directive\7f72111
-Node: #elif Directive\7f72778
-Node: Deleted Code\7f74156
-Node: Conditionals-Macros\7f75217
-Node: Assertions\7f78902
-Node: #error Directive\7f83137
-Node: Combining Sources\7f84577
-Node: Other Directives\7f87488
-Node: Output\7f88950
-Node: Invocation\7f90189
-Node: Concept Index\7f102013
-Node: Index\7f104866
-\1f
-End Tag Table
+++ /dev/null
-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.
-
-\1f
-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.
-
-\1f
-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::.
-
-\1f
-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.
-
-\1f
-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.
-
-\1f
-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.
-
-\1f
-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 <FILE>'
- 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 <x/*y>' 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.
-
-\1f
-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.
-
-\1f
-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.
-
-\1f
-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 <sys/signal.h>' 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 </usr/include/sys/signal.h>' 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 <sys/signal.h>' finds the file under `/usr/local/include'.
-If that file contains `#include_next <sys/signal.h>', it starts
-searching after that directory, and finds the file in `/usr/include'.
-
-\1f
-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.
-
-\1f
-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::.
-
-\1f
-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.
-
-\1f
-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.
-
-\1f
-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
- `""'.
-
-\1f
-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'.
-
-\1f
-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.
-
-\1f
-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.
-
-\1f
-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.
-
-\1f
-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.
-
-\1f
-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.
-
+++ /dev/null
-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.
-
-\1f
-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)'!
-
-\1f
-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))
-
-\1f
-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.
-
-\1f
-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').
-
-\1f
-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.
-
-\1f
-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'.
-
-\1f
-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'.)
-
-\1f
-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.
-
-\1f
-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.
-
-\1f
-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.
-
-\1f
-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.
-
-\1f
-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.
-
-\1f
-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.
-
-\1f
-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'.
-
-\1f
-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 `/*'.
-
-\1f
-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.
-
-\1f
-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::.
-
-\1f
-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.
-
-\1f
-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::.
-
-\1f
-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.
-
-\1f
-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.
-
+++ /dev/null
-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.
-
-\1f
-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 <FILE>'.
-
- 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 <FILE>' 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.
-
-\1f
-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.
-
-\1f
-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.
-
-
+++ /dev/null
-\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 <x/*y>} 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
-<sys/signal.h>} 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 </usr/include/sys/signal.h>} 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 <sys/signal.h>} finds the file under
-@file{/usr/local/include}. If that file contains @samp{#include_next
-<sys/signal.h>}, 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
+++ /dev/null
-/* 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 <malloc.h>
-// #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;
-// }
+++ /dev/null
-/* 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 <stdio.h>
-#include <stdlib.h>
-
-/* 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);
-}
-
-\f
-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
-}
+++ /dev/null
-/* 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 <stdlib.h>
-#ifdef MULTIBYTE_CHARS
-#include <locale.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
-
-/* 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. */
-};
-\f
-/* 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;
-}
-\f
-/* 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;
-}
+++ /dev/null
-/* 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 <string.h>
-#include <stdlib.h>
-
-/* 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]);
- }
-}
+++ /dev/null
-/* 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));
+++ /dev/null
-/* 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 <io.h>
-
-#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 <string.h>
-#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 <ctype.h>
-#include <stdio.h>
-#include <signal.h>
-#ifdef __STDC__
-#include <stdlib.h>
-#endif
-
-
-// PENDING: Straighten this out into configure
-#include <time.h> // all compilers need this
-#ifdef __MINGW32__
-#include <time.h>
-#else
-#ifdef __BORLANDC__
-#include <time.h>
-#else
-#ifndef VMS
-#ifndef USG
-#if !defined(_MSC_VER)
-// PENDING
-#include <time.h>
-#include <sys/time.h> /* for __DATE__ and __TIME__ */
-#include <sys/resource.h>
-#else
-/*#include <sys/param.h> CYGNUS LOCAL: shebs -noquiet */
-// #include <sys/times.h>
-#include <time.h>
-#include <fcntl.h>
-#endif // _MSC_VER
-#endif /* USG */
-#endif /* not VMS */
-#endif
-#endif
-
-/* This defines "errno" properly for VMS, and gives us EACCES. */
-#include <errno.h>
-
-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
-\f
-/* 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
-\f
-
-/* 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;
-};
-\f
-#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 ();
-\f
-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 <file> 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},
-};
-\f
-/* 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);
-}
-
-\f
-/*
- * 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));
-}
-\f
-/* 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);
-}
-\f
-/* 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;
-}
-\f
-/* 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;
-}
-\f
-/* 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++;
- }
-}
-\f
-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
-}
-\f
-/* 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);
-}
-
-\f
-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;
-}
-\f
-/* 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;
-}
-
-\f
-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);
- }
- }
-}
-\f
-/* 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;
-}
-\f
-/* 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;
- }
- }
-}
-\f
-/* Handle #include and #import.
- This function expects to see "fname" or <fname> 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, " ... <real contents of file> ...\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 <xyz.h>' (so the
- * code from case '<' is repeated here) and generates a warning.
- */
- cpp_warning (pfile,
- "VAX-C-style include specification found, use '#include <filename.h>' !");
- 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 <FILENAME>", 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;
-}
-
-\f
-/*
- * 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);
-}
-\f
-/* 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;
-}
-\f
-/*
- * 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;
-}
-\f
-/*
- * 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 <FILENAME>'");
- 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;
-}
-
-\f
-/* 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;
-}
-\f
-/* 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 <sys/types.h> 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;
-}
-\f
-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);
-}
-\f
-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;
-}
-\f
-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;
-}
-\f
-/* 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;
-}
-\f
-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;
- }
-}
-\f
-/* 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;
-}
-\f
-/* 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;
-}
-\f
-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 <errno.h>
-#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
- <errno.h>, 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.
- */
+++ /dev/null
-/* 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 <sys/types.h>
-#include <sys/stat.h>
-#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 <FILENAME>. */
- 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 <file> */
- /* 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
+++ /dev/null
-/* 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 <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#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);
-}
+++ /dev/null
-/* 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"
-\f
-/* 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
+++ /dev/null
-/* Definitions for IBM PS2 running AIX/386 with gas.
- From: Minh Tran-Le <TRANLE@intellicorp.com>
- 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)
+++ /dev/null
-/* Definitions for IBM PS2 running AIX/386.
- From: Minh Tran-Le <TRANLE@intellicorp.com>
- 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
-\f
-/* 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 */
+++ /dev/null
-/* 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)");
-\f
-/* 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; \
- } \
-}
-\f
-/* 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)
+++ /dev/null
-/* 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)");
-\f
-/* 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) */
-
-\f
-/* 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))
-\f
-/* 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
+++ /dev/null
-/* 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
+++ /dev/null
-/^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 \
-
+++ /dev/null
-/* 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 <phk@login.dkuug.dk>
-
-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"
-\f
-/* 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
-\f
-/* 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 */
+++ /dev/null
-/* 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)
-
-\f
-/* 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 */
+++ /dev/null
-/* Configuration for an i386 running GNU with ELF as the target machine. */
-
-/* This does it mostly for us. */
-#include <i386/linux.h>
-
-#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 <gnu.h>
+++ /dev/null
-/* 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)
-
-
+++ /dev/null
-#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
+++ /dev/null
-/* 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 */
+++ /dev/null
-/* 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 */
+++ /dev/null
-/* 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 <stdio.h>
-#include <setjmp.h>
-#include <ctype.h>
-#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 */
-
-\f
-/* 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;
-}
-\f
-/* 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 */
- }
- }
- }
-}
-
-\f
-/* 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;
-}
-
-\f
-/* 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;
-}
-
-\f
-/* 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;
-}
-
-\f
-/* 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);
-}
-\f
-/* 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);
- }
- }
-}
-\f
-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";
- }
-}
-\f
-/* 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 ();
-}
-
-\f
-/* 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);
- }
-}
-
-\f
-/* 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 "";
-}
-
-\f
-#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 "";
-}
-
-\f
-
-/* 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 "";
-}
-
-\f
-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);
-}
-\f
-/* 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);
-}
-\f
-/* 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;
-}
-\f
-/* 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;
-}
-
-\f
-/* 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);
-}
-
-\f
-/* 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;
-}
-
-\f
-/* 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;
-}
-\f
-
-/* 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);
-}
-
-\f
-/* 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;
-}
-
-\f
-/* 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");
- }
-}
-\f
-/* 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);
- }
-}
-\f
-/* 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);
- }
- }
-}
-\f
-/* 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;
- }
-}
-\f
-/* 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();
- }
-}
-\f
-/* 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;
- }
-}
-
-\f
-/* 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;
-}
-\f
-/* 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 ();
- }
-}
-\f
-/* 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);
-}
-\f
-/* 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);
-}
-\f
-/* 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;
-}
-\f
-#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];
-}
+++ /dev/null
-/* 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
-
-\f
-/* 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)
-
-\f
-/* 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)
-
-\f
-/* 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))
-
-\f
-/* 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); \
-}
-\f
-/* 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 */ \
- } \
-}
-\f
-/* 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
-\f
-/* 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)
-
-\f
-/* 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
-
-\f
-/* 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)
-\f
-/* 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; \
-}
-\f
-/* 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
-\f
-/* 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 '#'
-\f
-#define RET return ""
-#define AT_SP(mode) (gen_rtx (MEM, (mode), stack_pointer_rtx))
-\f
-/* 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 ();
-\f
-/*
-Local variables:
-version-control: t
-End:
-*/
+++ /dev/null
-;; 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'.
-\f
-;; "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;
-}")
-\f
-;;- 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]);
-}")
-\f
-;; 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);
-}")
-\f
-;; 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);
-}")
-
-\f
-;;- 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);
-}")
-\f
-;;- 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
-}")
-\f
-;; 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 ();
-}")
-
-\f
-;; 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);")
-\f
-;; 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 ();
-}")
-\f
-;;- 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 <augustss@cs.chalmers.se>
-;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"
- "")
-\f
-;;- 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"
- "")
-\f
-;;- 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"
- "")
-\f
-;;- 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"
- "")
-\f
-;; 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")
-*/
-\f
-;;- 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")
-
-*/
-\f
-;;- 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);")
-\f
-;;- 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);")
-\f
-;;- 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")
-\f
-;; 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")
-\f
-;;- 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")
-\f
-;;- 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);
-}")
-\f
-;;- 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);
-}")
-\f
-;;- 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);
-}")
-\f
-/*
-;; 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);
-}")
-\f
-;; 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);
-}")
-\f
-;; 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\"; ")
-\f
-;; 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")
-\f
-;; 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")
-\f
-;; 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 \"\";
-}")
-\f
-;; 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);")
-\f
-(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\";
-}")
+++ /dev/null
-/* 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"
+++ /dev/null
-/* 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)
+++ /dev/null
-/* 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"
+++ /dev/null
-/* 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"
+++ /dev/null
-/* 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 <i386/gstabs.h>
-#include <linux-aout.h> /* 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
-
-\f
-#undef LINK_SPEC
-#define LINK_SPEC "-m i386linux"
-
-/* Get perform_* macros to build libgcc.a. */
-#include "i386/perform.h"
+++ /dev/null
-/* 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 <i386/gstabs.h>
-#include <linux-aout.h> /* 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
-
-\f
-#undef LINK_SPEC
-#define LINK_SPEC ""
-
-/* Get perform_* macros to build libgcc.a. */
-#include <i386/perform.h>
+++ /dev/null
-/* 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 <i386/i386.h> /* Base i386 target machine definitions */
-#include <i386/att.h> /* Use the i386 AT&T assembler syntax */
-#include <linux.h> /* 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"
+++ /dev/null
-/* 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 <i386/gstabs.h>
-#include <lynx-ng.h>
-
-#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 }
+++ /dev/null
-/* 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 <i386/gstabs.h>
-#include <lynx.h>
-
-#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 }
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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 <i386/gstabs.h>
-
-/* Get perform_* macros to build libgcc.a. */
-#include <i386/perform.h>
-
-/* Get generic NetBSD definitions. */
-#include <netbsd.h>
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dunix -Di386 -D__NetBSD__ -Asystem(unix) -Asystem(NetBSD) -Acpu(i386) -Amachine(i386)"
-\f
-#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"
-\f
-/* 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
-\f
-/* 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"); \
- } \
-}
+++ /dev/null
-/* 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"
+++ /dev/null
-/* 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 */
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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 = "<no file>"; \
- \
- 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))
+++ /dev/null
-/* 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; \
-}
-
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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}}}}"
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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; \
- } \
-}
+++ /dev/null
-/* 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
-
+++ /dev/null
-/* 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
+++ /dev/null
-! 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
+++ /dev/null
-! 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:
+++ /dev/null
-! 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
+++ /dev/null
-/* 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')
-
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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)
+++ /dev/null
-/*
- * 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 : { }
- }
-}
+++ /dev/null
-/* 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"
+++ /dev/null
-/* 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
-\f
-/* ??? 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()
-\f
-/* 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)
+++ /dev/null
-/*
- * 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 : { }
- }
-}
+++ /dev/null
-/* 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
-\f
-/* 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)
-\f
-/* 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)
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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"
+++ /dev/null
-# 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
+++ /dev/null
-# The pushl in CTOR initialization interferes with frame pointer elimination.
-CRTSTUFF_T_CFLAGS = -fno-omit-frame-pointer
+++ /dev/null
-# The i386 md has all of these taken care of, according to sef.
-LIBGCC1 =
-CROSS_LIBGCC1 =
+++ /dev/null
-# The one that comes with the system is POSIX-compliant.
-LIMITS_H =
+++ /dev/null
-# 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
-
-# <limits.h> 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 ]
+++ /dev/null
-# 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
+++ /dev/null
-# 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 .
+++ /dev/null
-LIBGCC1 = libgcc1.null
-CROSS_LIBGCC1 = libgcc1.null
+++ /dev/null
-winnt.o: $(srcdir)/config/i386/winnt.c
- $(CC) -I. -I$(srcdir) -I$(srcdir)/config -c $(srcdir)/config/i386/winnt.c
+++ /dev/null
-/* 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"
+++ /dev/null
-/* 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); }
-\f
-/* 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))
-
+++ /dev/null
-/* 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 <i386/gas.h>
-
-/* 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
+++ /dev/null
-/* 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)
-
-
+++ /dev/null
-/* 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"
-
+++ /dev/null
-/* 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 <stdio.h>
-#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));
-}
-
+++ /dev/null
-# 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)
+++ /dev/null
-# Don't run fixproto
-STMP_FIXPROTO =
-CLIB=-lgnumalloc
+++ /dev/null
-CLIB = -lPW -lcposix
-X_CFLAGS = -D_POSIX_SOURCE
-ENQUIRE_LDFLAGS = -posix $(LDFLAGS)
+++ /dev/null
-CLIB = -lPW
-# One person said it needs -DPOSIX_JC, but daa@CERF.NET says no.
-X_CFLAGS = -D_SYSV3 -Xp
-ENQUIRE_LDFLAGS = $(LDFLAGS)
+++ /dev/null
-# 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./
+++ /dev/null
-# Make assignments for compiling on NeXT with their compiler version.
-CC=cc -traditional-cpp
-OLDCC=cc -traditional-cpp
+++ /dev/null
-# 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)
+++ /dev/null
-RANLIB = :
-RANLIB_TEST = false
-CC = rcc $(RCCFLAGS)
-OLDCC = rcc $(RCCFLAGS)
-RCCFLAGS = -Dunix -Di386 -DM_UNIX -DM_I386 -DNULL=0
-CCLIBFLAGS =
-CLIB = -lmalloc -lPW
+++ /dev/null
-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
+++ /dev/null
-/* 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
+++ /dev/null
-/* Configuration for GCC for Intel i386 running BSDI's BSD/386 as host. */
-
-#include "i386/xm-i386.h"
-
-#define HAVE_STRERROR
-
+++ /dev/null
-#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
+++ /dev/null
-/* Configuration for GCC for Intel i386 running FreeBSD as host. */
-
-#include <i386/xm-i386.h>
-#include <xm-freebsd.h>
+++ /dev/null
-/* Configuration for GCC for Intel i386 running GNU as host. */
-
-#include <i386/xm-i386.h>
-#include <xm-gnu.h>
-
+++ /dev/null
-/* 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"
+++ /dev/null
-#include "i386/xm-sysv3.h"
-
-#ifndef REAL_ARITHMETIC
-#define REAL_VALUE_ATOF(x, mode) strtod ((x), (char **)0)
-extern double strtod ();
-#endif
+++ /dev/null
-/* 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 <i386/xm-i386.h>
-/* #include <linux/linux.h> */
-
+++ /dev/null
-/* 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 <xm-lynx.h>
-
-/* 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"
+++ /dev/null
-/* Configuration for GCC for Intel i386 running NetBSD as host. */
-
-#include <i386/xm-i386.h>
-#include <xm-netbsd.h>
+++ /dev/null
-#include "i386/xm-i386.h"
-
-/* malloc does better with chunks the size of a page. */
-
-#define OBSTACK_CHUNK_SIZE (getpagesize ())
+++ /dev/null
-/* 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 <stdlib.h> /* 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"
+++ /dev/null
-/* 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
-
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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)
+++ /dev/null
-/* Configuration for GCC for Intel i386 running System V Release 3. */
-
-#include "i386/xm-i386.h"
-#include "xm-svr3.h"
+++ /dev/null
-/* 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 <alloca.h> /* 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
+++ /dev/null
-/* 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 ';'
+++ /dev/null
-/* 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"
+++ /dev/null
-# 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
+++ /dev/null
-/* Support functions for mingw32 and probably Borland C
- */
-#include <string.h>
-
-#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
+++ /dev/null
-#include "i386/win-nt.h"
+++ /dev/null
-# 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:
+++ /dev/null
-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
+++ /dev/null
-/^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/,/\f/ d
-/^# Build the include directory\./ r config/winnt/headers.mak
-/^# Build the include directory\./,/touch objc-headers/ d
-s/^\\f//
+++ /dev/null
-#include "/xm-winnt.h"
+++ /dev/null
-/*
- * @(#)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 <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <malloc.h>
-
-#include <string.h>
-#include <limits.h>
-#include <ctype.h>
-#include <errno.h>
-#include <dirent.h>
-
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-#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;
-}
-
+++ /dev/null
-/*
- * dirent.h
- */
-
-#ifndef _DIRENT_H
-# define _DIRENT_H
-
-# include <sys/types.h>
-# include <limits.h>
-
-#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
+++ /dev/null
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <stdio.h>
-#include <io.h>
-#include <fcntl.h>
-#include <process.h>
-
-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; i<oldsize; i++)
- {
- if (oldbuff [i] != newbuff [i])
- {
- free (oldbuff);
- free (newbuff);
- atleastone = 1;
- printf ("Fixing: %s\n", oneheader);
- return 0;
- }
- }
- free (oldbuff);
- free (newbuff);
- unlink (newheader);
- return 0;
-
-}
-
-/* Examine the contents of a directory and call doheader () for a regular file
- and recursively call dodir () for an enclosed directory. */
-
-int
-dodir (indir, outdir)
- char *indir, *outdir;
-{
- DIR *dir;
- struct dirent *dire;
- struct _stat statbuf;
- char *intempbuf, *outtempbuf;
-
- dir = opendir (indir);
- if (!dir) return 0;
-
- mkdirpath (concat3 ("include", "\\", newname (outdir)));
- while ((dire = readdir (dir)))
- {
- if (dire->d_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/<directory path>, where <directory path> 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));
-}
+++ /dev/null
-#include "/xm-winnt.h"
+++ /dev/null
-# 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
+++ /dev/null
-/* 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 <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <string.h>
-#include <process.h>
-
-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);
-}
+++ /dev/null
-# 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
-
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include <dirent.h>
-
-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<argc; i++)
- {
- char dirname[30], basename[30], fullname[30], *bp;
- int s;
- for (s=0; skips[s]; s++)
- if (strcmp(skips[s], argv[i]) == 0)
- break;
- if (skips[s])
- continue;
- strcpy(dirname, "lgcctmp/");
- strcpy(basename, "\0");
- if (strncmp(argv[i], "_fix", 4)==0)
- {
- strcat(basename, "fx");
- strcat(basename, argv[i]+4);
- }
- else if (strncmp(argv[i], "_float", 4)==0)
- {
- strcat(basename, "flt");
- strcat(basename, argv[i]+6);
- }
- else
- {
- strcat(basename, argv[i]);
- }
- strcpy (fullname, dirname);
- strcat (fullname, basename);
- fprintf(batfile, "%s -c lgcctmp/%s.c\n", cc, basename);
- fprintf(batfile, "copy %s.obj lgcctmp\n", basename);
- bp = fullname + strlen(fullname);
- strcpy(bp, ".c");
- cfile = fopen(fullname, "w");
- if (cfile)
- {
- *bp = 0;
- fprintf(cfile, "#define L%s\n#include \"%s\"\n", argv[i], csrc);
- fclose(cfile);
- }
- else
- perror(fullname);
- }
-
- fclose(batfile);
- return 0;
-}
+++ /dev/null
-#define MULTILIB_SELECT ". ;"
+++ /dev/null
-int
-access (const char *path, int mode)
-{
- return _access (path, mode);
-}
-
-int
-chmod (const char *filename, int pmode)
-{
- return _chmod (filename, pmode);
-}
-
-int
-close (int handle)
-{
- return _close (handle);
-}
-
-char *
-mktemp (char *template)
-{
- return (char *) _mktemp (template);
-}
-
-int
-open (const char *filename, int oflag, int pmode)
-{
- return _open (filename, oflag, pmode);
-}
-
-int
-read (int handle, void *buffer, unsigned int count)
-{
- return _read (handle, buffer, count);
-}
-
-int
-unlink (const char *path)
-{
- return _unlink (path);
-}
-
-int
-write (int handle, void *buffer, unsigned int count)
-{
- return _write (handle, buffer, count);
-}
+++ /dev/null
-/* This is a kludge to get around the Microsoft C spawn functions' propensity
- to remove the outermost set of double quotes from all arguments. */
-
-#define index(s,c) strchr((s),(c))
-
-extern char *malloc ();
-
-const char * const *
-fix_argv (argv)
- char **argv;
-{
- static char sh_chars[] = "\"";
-
- int i, len;
- char *new_argv;
- char *p, *ap;
-
- for (i=1; argv[i]; i++)
- {
-
- len = strlen (argv[i]);
- new_argv = malloc (2*len+3);
- ap = new_argv;
-
- for (p = argv[i]; *p != '\0'; ++p)
- {
- if (index (sh_chars, *p) != 0)
- *ap++ = '\\';
- *ap++ = *p;
- }
- *ap = '\0';
- argv[i] = new_argv;
- }
-
- return (const char * const *) argv;
-}
-
-int __spawnv (mode, cmdname, argv)
- int mode;
- const char *cmdname;
- char **argv;
-{
- _spawnv (mode, cmdname, fix_argv (argv));
-}
-
-int __spawnvp (mode, cmdname, argv)
- int mode;
- const char *cmdname;
- char **argv;
-{
- _spawnvp (mode, cmdname, fix_argv (argv));
-}
-
-int spawnve (mode, cmdname, argv, envp)
- int mode;
- const char *cmdname;
- char **argv;
- const char *const *envp;
-{
- _spawnve (mode, cmdname, fix_argv (argv), envp);
-}
-
-int __spawnvpe (mode, cmdname, argv, envp)
- int mode;
- const char *cmdname;
- char **argv;
- const char *const *envp;
-{
- _spawnvpe (mode, cmdname, fix_argv (argv), envp);
-}
-
+++ /dev/null
-#include "/xm-winnt.h"
+++ /dev/null
-#include "/win-nt.h"
+++ /dev/null
-/* 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 <stdlib.h>
-
-#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)
-
+++ /dev/null
-/* 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
+++ /dev/null
-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
+++ /dev/null
-/* 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 <stdlib.h>
-
-#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)
-