summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1998-02-14 19:27:17 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1998-02-14 19:27:17 +0000
commit6de8cb0481bd793706e38dead271f9233a57b7e5 (patch)
tree7ff9ff6922a48636469d3b019d912ee0b7894c00
parent627e15b4811e5758670f68174f71540e63fb4040 (diff)
-rw-r--r--gnu/usr.bin/gcc/config/a29k/udi.h94
-rw-r--r--gnu/usr.bin/gcc/config/alpha/elf.h506
-rw-r--r--gnu/usr.bin/gcc/config/alpha/osf2or3.h24
-rw-r--r--gnu/usr.bin/gcc/config/alpha/t-vms6
-rw-r--r--gnu/usr.bin/gcc/config/alpha/vms-tramp.asm22
-rw-r--r--gnu/usr.bin/gcc/config/alpha/vms.h461
-rw-r--r--gnu/usr.bin/gcc/config/alpha/xm-vms.h82
-rw-r--r--gnu/usr.bin/gcc/config/arc/arc.c2212
-rw-r--r--gnu/usr.bin/gcc/config/arc/arc.h1643
-rw-r--r--gnu/usr.bin/gcc/config/arc/arc.md1630
-rw-r--r--gnu/usr.bin/gcc/config/arc/initfini.c157
-rw-r--r--gnu/usr.bin/gcc/config/arc/lib1funcs.asm273
-rw-r--r--gnu/usr.bin/gcc/config/arc/t-arc72
-rw-r--r--gnu/usr.bin/gcc/config/arc/xm-arc.h47
-rw-r--r--gnu/usr.bin/gcc/config/arm/aof.h453
-rw-r--r--gnu/usr.bin/gcc/config/arm/aout.h259
-rw-r--r--gnu/usr.bin/gcc/config/arm/coff.h209
-rw-r--r--gnu/usr.bin/gcc/config/arm/linux-gas.h34
-rw-r--r--gnu/usr.bin/gcc/config/arm/linux.h72
-rw-r--r--gnu/usr.bin/gcc/config/arm/netbsd.h143
-rw-r--r--gnu/usr.bin/gcc/config/arm/semiaof.h43
-rw-r--r--gnu/usr.bin/gcc/config/arm/t-bare30
-rw-r--r--gnu/usr.bin/gcc/config/arm/t-linux19
-rw-r--r--gnu/usr.bin/gcc/config/arm/t-netbsd7
-rw-r--r--gnu/usr.bin/gcc/config/arm/t-semiaof63
-rw-r--r--gnu/usr.bin/gcc/config/arm/xm-linux.h24
-rw-r--r--gnu/usr.bin/gcc/config/arm/xm-netbsd.h7
-rw-r--r--gnu/usr.bin/gcc/config/dbx.h30
-rw-r--r--gnu/usr.bin/gcc/config/dbxcoff.h87
-rw-r--r--gnu/usr.bin/gcc/config/float-i128.h96
-rw-r--r--gnu/usr.bin/gcc/config/float-i32.h96
-rw-r--r--gnu/usr.bin/gcc/config/float-i64.h96
-rw-r--r--gnu/usr.bin/gcc/config/float-sh.h130
-rw-r--r--gnu/usr.bin/gcc/config/float-vax.h96
-rw-r--r--gnu/usr.bin/gcc/config/i370/i370.c584
-rw-r--r--gnu/usr.bin/gcc/config/i370/i370.h1441
-rw-r--r--gnu/usr.bin/gcc/config/i370/t-i3704
-rw-r--r--gnu/usr.bin/gcc/config/i370/xm-i370.h53
-rw-r--r--gnu/usr.bin/gcc/config/i386/cygwin32.asm32
-rw-r--r--gnu/usr.bin/gcc/config/i386/cygwin32.h207
-rw-r--r--gnu/usr.bin/gcc/config/i386/dgux.c190
-rw-r--r--gnu/usr.bin/gcc/config/i386/dgux.h265
-rw-r--r--gnu/usr.bin/gcc/config/i386/freebsd-elf.h187
-rw-r--r--gnu/usr.bin/gcc/config/i386/gmon-sol2.c402
-rw-r--r--gnu/usr.bin/gcc/config/i386/go32-rtems.h32
-rw-r--r--gnu/usr.bin/gcc/config/i386/mingw32.h93
-rw-r--r--gnu/usr.bin/gcc/config/i386/moss.h34
-rw-r--r--gnu/usr.bin/gcc/config/i386/ptx4-i.h247
-rw-r--r--gnu/usr.bin/gcc/config/i386/rtems.h28
-rw-r--r--gnu/usr.bin/gcc/config/i386/sco5.h967
-rw-r--r--gnu/usr.bin/gcc/config/i386/sol2-gc1.asm160
-rw-r--r--gnu/usr.bin/gcc/config/i386/sol2dbg.h16
-rw-r--r--gnu/usr.bin/gcc/config/i386/t-cygwin327
-rw-r--r--gnu/usr.bin/gcc/config/i386/t-dgux4
-rw-r--r--gnu/usr.bin/gcc/config/i386/t-freebsd5
-rw-r--r--gnu/usr.bin/gcc/config/i386/t-go322
-rw-r--r--gnu/usr.bin/gcc/config/i386/t-osf2
-rw-r--r--gnu/usr.bin/gcc/config/i386/t-sco516
-rw-r--r--gnu/usr.bin/gcc/config/i386/x-cygwin324
-rw-r--r--gnu/usr.bin/gcc/config/i386/x-dgux11
-rw-r--r--gnu/usr.bin/gcc/config/i386/x-sco510
-rw-r--r--gnu/usr.bin/gcc/config/i386/xm-cygwin32.h26
-rw-r--r--gnu/usr.bin/gcc/config/i386/xm-dgux.h12
-rw-r--r--gnu/usr.bin/gcc/config/i386/xm-go32.h28
-rw-r--r--gnu/usr.bin/gcc/config/i386/xm-mingw32.h45
-rw-r--r--gnu/usr.bin/gcc/config/i386/xm-sco5.h18
-rw-r--r--gnu/usr.bin/gcc/config/i960/rtems.h28
-rw-r--r--gnu/usr.bin/gcc/config/libgloss.h35
-rw-r--r--gnu/usr.bin/gcc/config/m32r/initfini.c169
-rw-r--r--gnu/usr.bin/gcc/config/m32r/m32r.c1835
-rw-r--r--gnu/usr.bin/gcc/config/m32r/m32r.h1867
-rw-r--r--gnu/usr.bin/gcc/config/m32r/m32r.md1469
-rw-r--r--gnu/usr.bin/gcc/config/m32r/t-m32r57
-rw-r--r--gnu/usr.bin/gcc/config/m32r/xm-m32r.h47
-rw-r--r--gnu/usr.bin/gcc/config/m68k/a-ux.h206
-rw-r--r--gnu/usr.bin/gcc/config/m68k/aux-crt1.c134
-rw-r--r--gnu/usr.bin/gcc/config/m68k/aux-crt2.asm42
-rw-r--r--gnu/usr.bin/gcc/config/m68k/aux-crtn.asm26
-rw-r--r--gnu/usr.bin/gcc/config/m68k/aux-exit.c99
-rw-r--r--gnu/usr.bin/gcc/config/m68k/aux-low.gld38
-rw-r--r--gnu/usr.bin/gcc/config/m68k/aux-mcount.c69
-rw-r--r--gnu/usr.bin/gcc/config/m68k/auxas.h189
-rw-r--r--gnu/usr.bin/gcc/config/m68k/auxgas.h56
-rw-r--r--gnu/usr.bin/gcc/config/m68k/auxgld.h29
-rw-r--r--gnu/usr.bin/gcc/config/m68k/auxld.h35
-rw-r--r--gnu/usr.bin/gcc/config/m68k/m68k-psos.h67
-rw-r--r--gnu/usr.bin/gcc/config/m68k/mot3300-crt0.S98
-rw-r--r--gnu/usr.bin/gcc/config/m68k/mot3300Mcrt0.S142
-rw-r--r--gnu/usr.bin/gcc/config/m68k/rtems.h28
-rw-r--r--gnu/usr.bin/gcc/config/m68k/t-aux44
-rw-r--r--gnu/usr.bin/gcc/config/m68k/t-linux-aout5
-rw-r--r--gnu/usr.bin/gcc/config/m68k/t-mot330010
-rw-r--r--gnu/usr.bin/gcc/config/m68k/t-mot3300-gald13
-rw-r--r--gnu/usr.bin/gcc/config/m68k/t-mot3300-gas13
-rw-r--r--gnu/usr.bin/gcc/config/m68k/t-mot3300-gld12
-rw-r--r--gnu/usr.bin/gcc/config/m68k/x-mot3300-gas12
-rw-r--r--gnu/usr.bin/gcc/config/m68k/xm-aux.h9
-rw-r--r--gnu/usr.bin/gcc/config/m88k/t-dguxbcs28
-rw-r--r--gnu/usr.bin/gcc/config/mips/r3900.h71
-rw-r--r--gnu/usr.bin/gcc/config/mips/rtems64.h28
-rw-r--r--gnu/usr.bin/gcc/config/mips/sni-gas.h43
-rw-r--r--gnu/usr.bin/gcc/config/mips/sni-svr4.h97
-rw-r--r--gnu/usr.bin/gcc/config/mips/x-sni-svr418
-rw-r--r--gnu/usr.bin/gcc/config/mn10200/divmod.c50
-rw-r--r--gnu/usr.bin/gcc/config/mn10200/lib1funcs.asm609
-rw-r--r--gnu/usr.bin/gcc/config/mn10200/mn10200.c1532
-rw-r--r--gnu/usr.bin/gcc/config/mn10200/mn10200.h1078
-rw-r--r--gnu/usr.bin/gcc/config/mn10200/mn10200.md1978
-rw-r--r--gnu/usr.bin/gcc/config/mn10200/t-mn1020050
-rw-r--r--gnu/usr.bin/gcc/config/mn10200/udivmod.c14
-rw-r--r--gnu/usr.bin/gcc/config/mn10200/udivmodsi4.c24
-rw-r--r--gnu/usr.bin/gcc/config/mn10200/xm-mn10200.h47
-rw-r--r--gnu/usr.bin/gcc/config/mn10300/mn10300.c1065
-rw-r--r--gnu/usr.bin/gcc/config/mn10300/mn10300.h1016
-rw-r--r--gnu/usr.bin/gcc/config/mn10300/mn10300.md1415
-rw-r--r--gnu/usr.bin/gcc/config/mn10300/t-mn1030020
-rw-r--r--gnu/usr.bin/gcc/config/mn10300/xm-mn10300.h47
-rw-r--r--gnu/usr.bin/gcc/config/pa/ee.asm261
-rw-r--r--gnu/usr.bin/gcc/config/pa/ee_fp.asm274
-rw-r--r--gnu/usr.bin/gcc/config/pa/lib1funcs.asm1146
-rw-r--r--gnu/usr.bin/gcc/config/pa/pa-gas.h21
-rw-r--r--gnu/usr.bin/gcc/config/pa/pa-hpux10.h71
-rw-r--r--gnu/usr.bin/gcc/config/pa/pa-pro-end.h41
-rw-r--r--gnu/usr.bin/gcc/config/pa/pa-pro.h78
-rw-r--r--gnu/usr.bin/gcc/config/pa/rtems.h26
-rw-r--r--gnu/usr.bin/gcc/config/pa/t-pro38
-rw-r--r--gnu/usr.bin/gcc/config/pa/xm-papro.h58
-rw-r--r--gnu/usr.bin/gcc/config/psos.h183
-rw-r--r--gnu/usr.bin/gcc/config/ptx4.h859
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/cygwin32.h67
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/eabi-ci.asm119
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/eabi-cn.asm109
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/linux.h67
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/nt-ci.asm48
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/nt-cn.asm48
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/ntstack.asm42
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/rtems.h32
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/sol-c0.c122
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/sol-ci.asm104
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/sol-cn.asm82
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/sol2.h178
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/t-ppccomm73
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/t-ppcos12
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/t-winnt35
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/t-xnewas58
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/t-xrs600028
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/tramp.asm120
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/vxppc.h63
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/win-nt.h478
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/x-cygwin324
-rw-r--r--gnu/usr.bin/gcc/config/rs6000/xm-cygwin32.h26
-rw-r--r--gnu/usr.bin/gcc/config/sh/elf.h122
-rw-r--r--gnu/usr.bin/gcc/config/sh/rtems.h28
-rw-r--r--gnu/usr.bin/gcc/config/sparc/aout.h26
-rw-r--r--gnu/usr.bin/gcc/config/sparc/elf.h42
-rw-r--r--gnu/usr.bin/gcc/config/sparc/linux-aout.h111
-rw-r--r--gnu/usr.bin/gcc/config/sparc/linux.h234
-rw-r--r--gnu/usr.bin/gcc/config/sparc/linux64.h236
-rw-r--r--gnu/usr.bin/gcc/config/sparc/rtems.h28
-rw-r--r--gnu/usr.bin/gcc/config/sparc/sol2-g1.asm88
-rw-r--r--gnu/usr.bin/gcc/config/sparc/splet.h53
-rw-r--r--gnu/usr.bin/gcc/config/sparc/sun4gas.h27
-rw-r--r--gnu/usr.bin/gcc/config/sparc/t-elf39
-rw-r--r--gnu/usr.bin/gcc/config/sparc/t-linux6
-rw-r--r--gnu/usr.bin/gcc/config/sparc/t-splet23
-rw-r--r--gnu/usr.bin/gcc/config/sparc/vxsim.h131
-rw-r--r--gnu/usr.bin/gcc/config/sparc/xm-linux.h28
-rw-r--r--gnu/usr.bin/gcc/config/sparc/xm-sp64.h25
-rw-r--r--gnu/usr.bin/gcc/config/t-gnu13
-rw-r--r--gnu/usr.bin/gcc/config/t-linux10
-rw-r--r--gnu/usr.bin/gcc/config/t-linux-aout5
-rw-r--r--gnu/usr.bin/gcc/config/t-linux-gnulibc12
-rw-r--r--gnu/usr.bin/gcc/config/t-netbsd8
-rw-r--r--gnu/usr.bin/gcc/config/t-rtems2
-rw-r--r--gnu/usr.bin/gcc/config/v850/lib1funcs.asm1269
-rw-r--r--gnu/usr.bin/gcc/config/v850/t-v85052
-rw-r--r--gnu/usr.bin/gcc/config/v850/v850.c2284
-rw-r--r--gnu/usr.bin/gcc/config/v850/v850.h1475
-rw-r--r--gnu/usr.bin/gcc/config/v850/v850.md1273
-rw-r--r--gnu/usr.bin/gcc/config/v850/xm-v850.h49
-rw-r--r--gnu/usr.bin/gcc/config/xm-std32.h34
-rw-r--r--gnu/usr.bin/gcc/cp/ChangeLog.19451
-rw-r--r--gnu/usr.bin/gcc/cp/NEWS180
-rw-r--r--gnu/usr.bin/gcc/cp/cp-tree.def169
-rw-r--r--gnu/usr.bin/gcc/cp/exception.cc195
-rw-r--r--gnu/usr.bin/gcc/cp/friend.c440
-rw-r--r--gnu/usr.bin/gcc/cp/g++FAQ.texi2158
-rw-r--r--gnu/usr.bin/gcc/cp/g++spec.c255
-rw-r--r--gnu/usr.bin/gcc/cp/inc/exception42
-rw-r--r--gnu/usr.bin/gcc/cp/inc/new48
-rw-r--r--gnu/usr.bin/gcc/cp/inc/new.h13
-rw-r--r--gnu/usr.bin/gcc/cp/inc/typeinfo71
-rw-r--r--gnu/usr.bin/gcc/cp/mpw-config.in11
-rw-r--r--gnu/usr.bin/gcc/cp/mpw-make.sed112
-rw-r--r--gnu/usr.bin/gcc/cp/new.cc31
-rw-r--r--gnu/usr.bin/gcc/cp/new1.cc54
-rw-r--r--gnu/usr.bin/gcc/cp/new2.cc33
-rw-r--r--gnu/usr.bin/gcc/cp/rtti.c1394
-rw-r--r--gnu/usr.bin/gcc/cp/tinfo.cc125
-rw-r--r--gnu/usr.bin/gcc/cp/tinfo.h55
-rw-r--r--gnu/usr.bin/gcc/cp/tinfo2.cc323
-rw-r--r--gnu/usr.bin/gcc/ginclude/ppc-asm.h170
-rw-r--r--gnu/usr.bin/gcc/ginclude/va-arc.h111
-rw-r--r--gnu/usr.bin/gcc/ginclude/va-m32r.h86
-rw-r--r--gnu/usr.bin/gcc/ginclude/va-mn10200.h37
-rw-r--r--gnu/usr.bin/gcc/ginclude/va-mn10300.h35
-rw-r--r--gnu/usr.bin/gcc/ginclude/va-sh.h199
-rw-r--r--gnu/usr.bin/gcc/ginclude/va-v850.h34
-rw-r--r--gnu/usr.bin/gcc/objc/Make-lang.in308
-rw-r--r--gnu/usr.bin/gcc/objc/Makefile.in91
-rw-r--r--gnu/usr.bin/gcc/objc/README.threads50
-rw-r--r--gnu/usr.bin/gcc/objc/THREADS374
-rw-r--r--gnu/usr.bin/gcc/objc/THREADS.MACH23
-rw-r--r--gnu/usr.bin/gcc/objc/config-lang.in37
-rw-r--r--gnu/usr.bin/gcc/objc/libobjc.def161
-rw-r--r--gnu/usr.bin/gcc/objc/libobjc_entry.c55
-rw-r--r--gnu/usr.bin/gcc/objc/linking.m40
-rw-r--r--gnu/usr.bin/gcc/objc/nil_method.c40
-rw-r--r--gnu/usr.bin/gcc/objc/objc-act.c8410
-rw-r--r--gnu/usr.bin/gcc/objc/objc-act.h117
-rw-r--r--gnu/usr.bin/gcc/objc/objc-list.h147
-rw-r--r--gnu/usr.bin/gcc/objc/objc-parse.c5111
-rw-r--r--gnu/usr.bin/gcc/objc/objc-parse.y2945
-rw-r--r--gnu/usr.bin/gcc/objc/objc-tree.def37
-rw-r--r--gnu/usr.bin/gcc/objc/objc.gperf64
-rw-r--r--gnu/usr.bin/gcc/objc/thr-decosf1.c281
-rw-r--r--gnu/usr.bin/gcc/objc/thr-irix.c235
-rw-r--r--gnu/usr.bin/gcc/objc/thr-mach.c312
-rw-r--r--gnu/usr.bin/gcc/objc/thr-os2.c267
-rw-r--r--gnu/usr.bin/gcc/objc/thr-posix.c229
-rw-r--r--gnu/usr.bin/gcc/objc/thr-pthreads.c218
-rw-r--r--gnu/usr.bin/gcc/objc/thr-single.c192
-rw-r--r--gnu/usr.bin/gcc/objc/thr-solaris.c259
-rw-r--r--gnu/usr.bin/gcc/objc/thr-win32.c272
-rw-r--r--gnu/usr.bin/gcc/objc/thr.c534
-rw-r--r--gnu/usr.bin/gcc/objc/thr.h143
236 files changed, 79946 insertions, 0 deletions
diff --git a/gnu/usr.bin/gcc/config/a29k/udi.h b/gnu/usr.bin/gcc/config/a29k/udi.h
new file mode 100644
index 00000000000..400ffbbe985
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/a29k/udi.h
@@ -0,0 +1,94 @@
+/* Definitions of target machine for GNU compiler, for AMD Am29000 CPU
+ running over UDI using COFF.
+ Copyright (C) 1994, 1996 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. */
+
+/* Support the ctors and dtors sections for g++. */
+
+#define CTORS_SECTION_ASM_OP "\t.use .ctors"
+#define DTORS_SECTION_ASM_OP "\t.use .dtors"
+
+/* A list of other sections which the compiler might be "in" at any
+ given time. */
+
+#undef EXTRA_SECTIONS
+#define EXTRA_SECTIONS readonly_data, in_ctors, in_dtors
+
+/* A list of extra section function definitions. */
+
+#undef EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS \
+ READONLY_DATA_FUNCTION \
+ CTORS_SECTION_FUNCTION \
+ DTORS_SECTION_FUNCTION
+
+#define READONLY_DATA_FUNCTION \
+void \
+literal_section () \
+{ \
+ if (in_section != readonly_data) \
+ { \
+ fprintf (asm_out_file, "%s\n", READONLY_DATA_SECTION_ASM_OP); \
+ in_section = readonly_data; \
+ } \
+} \
+
+#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 ".word"
+
+/* 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)
diff --git a/gnu/usr.bin/gcc/config/alpha/elf.h b/gnu/usr.bin/gcc/config/alpha/elf.h
new file mode 100644
index 00000000000..8a7f06a928b
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/alpha/elf.h
@@ -0,0 +1,506 @@
+/* Definitions of target machine for GNU compiler, for DEC Alpha w/ELF.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.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. */
+
+/* This is used on Alpha platforms that use the ELF format.
+ Currently only GNU/Linux uses this. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (Alpha GNU/Linux with ELF)");
+
+#undef OBJECT_FORMAT_COFF
+#undef EXTENDED_COFF
+#define OBJECT_FORMAT_ELF
+
+#define SDB_DEBUGGING_INFO
+
+#undef ASM_FINAL_SPEC
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "\
+-D__alpha -D__alpha__ -D__linux__ -D__linux -D_LONGLONG -Dlinux -Dunix \
+-Asystem(linux) -Acpu(alpha) -Amachine(alpha) -D__ELF__"
+
+#undef LINK_SPEC
+#ifdef USE_GNULIBC_1
+#define LINK_SPEC "-m elf64alpha -G 8 %{O*:-O3} %{!O*:-O1} \
+ %{shared:-shared} \
+ %{!shared: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \
+ %{static:-static}}"
+#else
+#define LINK_SPEC "-m elf64alpha -G 8 %{O*:-O3} %{!O*:-O1} \
+ %{shared:-shared} \
+ %{!shared: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \
+ %{static:-static}}"
+#endif
+
+/* Output at beginning of assembler file. */
+
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) \
+{ \
+ alpha_write_verstamp (FILE); \
+ output_file_directive (FILE, main_input_filename); \
+ fprintf (FILE, "\t.version\t\"01.01\"\n"); \
+ fprintf (FILE, "\t.set noat\n"); \
+}
+
+#define ASM_OUTPUT_SOURCE_LINE(STREAM, LINE) \
+ alpha_output_lineno (STREAM, LINE)
+extern void alpha_output_lineno ();
+
+extern void output_file_directive ();
+
+/* 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"
+
+#ifdef IDENTIFY_WITH_IDENT
+#define ASM_IDENTIFY_GCC(FILE) /* nothing */
+#define ASM_IDENTIFY_LANGUAGE(FILE) \
+ fprintf(FILE, "\t%s \"GCC (%s) %s\"\n", IDENT_ASM_OP, \
+ lang_identify(), version_string)
+#else
+#define ASM_FILE_END(FILE) \
+do { \
+ fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \
+ IDENT_ASM_OP, version_string); \
+ } while (0)
+#endif
+
+/* Allow #sccs in preprocessor. */
+
+#define SCCS_DIRECTIVE
+
+/* Output #ident as a .ident. */
+
+#define ASM_OUTPUT_IDENT(FILE, NAME) \
+ fprintf (FILE, "\t%s\t\"%s\"\n", IDENT_ASM_OP, NAME);
+
+/* This is how to allocate empty space in some section. The .zero
+ pseudo-op is used for this on most svr4 assemblers. */
+
+#define SKIP_ASM_OP ".zero"
+
+#undef ASM_OUTPUT_SKIP
+#define ASM_OUTPUT_SKIP(FILE,SIZE) \
+ fprintf (FILE, "\t%s\t%u\n", SKIP_ASM_OP, (SIZE))
+
+/* Output the label which precedes a jumptable. Note that for all svr4
+ systems where we actually generate jumptables (which is to say every
+ svr4 target except i386, where we use casesi instead) we put the jump-
+ tables into the .rodata section and since other stuff could have been
+ put into the .rodata section prior to any given jumptable, we have to
+ make sure that the location counter for the .rodata section gets pro-
+ perly re-aligned prior to the actual beginning of the jump table. */
+
+#define ALIGN_ASM_OP ".align"
+
+#ifndef ASM_OUTPUT_BEFORE_CASE_LABEL
+#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
+ ASM_OUTPUT_ALIGN ((FILE), 2);
+#endif
+
+#undef ASM_OUTPUT_CASE_LABEL
+#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,JUMPTABLE) \
+ do { \
+ ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE) \
+ ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); \
+ } while (0)
+
+/* The standard SVR4 assembler seems to require that certain builtin
+ library routines (e.g. .udiv) be explicitly declared as .globl
+ in each assembly file where they are referenced. */
+
+#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
+ ASM_GLOBALIZE_LABEL (FILE, XSTR (FUN, 0))
+
+/* This says how to output assembler code to declare an
+ uninitialized external linkage data object. Under SVR4,
+ the linker seems to want the alignment of data objects
+ to depend on their types. We do exactly that here. */
+
+#define COMMON_ASM_OP ".comm"
+
+#undef ASM_OUTPUT_ALIGNED_COMMON
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
+do { \
+ fprintf ((FILE), "\t%s\t", COMMON_ASM_OP); \
+ assemble_name ((FILE), (NAME)); \
+ fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
+} while (0)
+
+/* This says how to output assembler code to declare an
+ uninitialized internal linkage data object. Under SVR4,
+ the linker seems to want the alignment of data objects
+ to depend on their types. We do exactly that here. */
+
+#define LOCAL_ASM_OP ".local"
+
+#undef ASM_OUTPUT_ALIGNED_LOCAL
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
+do { \
+ fprintf ((FILE), "\t%s\t", LOCAL_ASM_OP); \
+ assemble_name ((FILE), (NAME)); \
+ fprintf ((FILE), "\n"); \
+ ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \
+} while (0)
+
+/* This is the pseudo-op used to generate a 64-bit word of data with a
+ specific value in some section. */
+
+#define INT_ASM_OP ".quad"
+
+/* This is the pseudo-op used to generate a contiguous sequence of byte
+ values from a double-quoted string WITHOUT HAVING A TERMINATING NUL
+ AUTOMATICALLY APPENDED. This is the same for most svr4 assemblers. */
+
+#undef ASCII_DATA_ASM_OP
+#define ASCII_DATA_ASM_OP ".ascii"
+
+/* 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. */
+
+#define USE_CONST_SECTION 1
+
+#define CONST_SECTION_ASM_OP ".section\t.rodata"
+
+/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
+
+ Note that we want to give these sections the SHF_WRITE attribute
+ because these sections will actually contain data (i.e. tables of
+ addresses of functions in the current root executable or shared library
+ file) and, in the case of a shared library, the relocatable addresses
+ will have to be properly resolved/relocated (and then written into) by
+ the dynamic linker when it actually attaches the given shared library
+ to the executing process. (Note that on SVR4, you may wish to use the
+ `-z text' option to the ELF linker, when building a shared library, as
+ an additional check that you are doing everything right. But if you do
+ use the `-z text' option when building a shared library, you will get
+ errors unless the .ctors and .dtors sections are marked as writable
+ via the SHF_WRITE attribute.) */
+
+#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\""
+#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\""
+
+/* On svr4, we *do* have support for the .init and .fini sections, and we
+ can put stuff in there to be executed before and after `main'. We let
+ crtstuff.c and other files know this by defining the following symbols.
+ The definitions say how to change sections to the .init and .fini
+ sections. This is the same for all known svr4 assemblers. */
+
+#define INIT_SECTION_ASM_OP ".section\t.init"
+#define FINI_SECTION_ASM_OP ".section\t.fini"
+
+/* A default list of other sections which we might be "in" at any given
+ time. For targets that use additional sections (e.g. .tdesc) you
+ should override this definition in the target-specific file which
+ includes this file. */
+
+#undef EXTRA_SECTIONS
+#define EXTRA_SECTIONS in_const, in_ctors, in_dtors
+
+/* A default list of extra section function definitions. For targets
+ that use additional sections (e.g. .tdesc) you should override this
+ definition in the target-specific file which includes this file. */
+
+#undef EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS \
+ CONST_SECTION_FUNCTION \
+ CTORS_SECTION_FUNCTION \
+ DTORS_SECTION_FUNCTION
+
+#undef READONLY_DATA_SECTION
+#define READONLY_DATA_SECTION() const_section ()
+
+extern void text_section ();
+
+#define CONST_SECTION_FUNCTION \
+void \
+const_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; \
+ } \
+}
+
+#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; \
+ } \
+}
+
+/* Switch into a generic section.
+ This is currently only used to support section attributes.
+
+ We make the section read-only and executable for a function decl,
+ read-only for a const data decl, and writable for a non-const data decl. */
+#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
+ fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, \
+ (DECL) && TREE_CODE (DECL) == FUNCTION_DECL ? "ax" : \
+ (DECL) && DECL_READONLY_SECTION (DECL, RELOC) ? "a" : "aw")
+
+
+/* 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)
+
+/* 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 ((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. */
+
+#undef SELECT_RTX_SECTION
+#define SELECT_RTX_SECTION(MODE,RTX) const_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"
+
+/* 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)
+
+/* This is how we tell the assembler that two symbols have the same value. */
+
+#define ASM_OUTPUT_DEF(FILE,NAME1,NAME2) \
+ do { assemble_name(FILE, NAME1); \
+ fputs(" = ", FILE); \
+ assemble_name(FILE, NAME2); \
+ 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"
+
+/* 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 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) \
+ { \
+ 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))); \
+ } \
+ } while (0)
+
+/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
+ ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
+ corresponds to a particular byte value [0..255]. For any
+ given byte value, if the value in the corresponding table
+ position is zero, the given character can be output directly.
+ If the table value is 1, the byte must be output as a \ooo
+ octal escape. If the tables value is anything else, then the
+ byte value should be output as a \ followed by the value
+ in the table. Note that we can use standard UN*X escape
+ sequences for many control characters, but we don't use
+ \a to represent BEL because some svr4 assemblers (e.g. on
+ the i386) don't know about that. Also, we don't use \v
+ since some versions of gas, such as 2.2 did not accept it. */
+
+#define ESCAPES \
+"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
+\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\
+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"
+
+/* Some svr4 assemblers have a limit on the number of characters which
+ can appear in the operand of a .string directive. If your assembler
+ has such a limitation, you should define STRING_LIMIT to reflect that
+ limit. Note that at least some svr4 assemblers have a limit on the
+ actual number of bytes in the double-quoted string, and that they
+ count each character in an escape sequence as one byte. Thus, an
+ escape sequence like \377 would count as four bytes.
+
+ If your target assembler doesn't support the .string directive, you
+ should define this to zero.
+*/
+
+#define STRING_LIMIT ((unsigned) 256)
+
+#define STRING_ASM_OP ".string"
+
+/*
+ * We always use gas here, so we don't worry about ECOFF assembler problems.
+ */
+#undef TARGET_GAS
+#define TARGET_GAS (1)
+
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+/* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add
+ the GNU/Linux magical crtbegin.o file (see crtstuff.c) which
+ provides part of the support for getting C++ file-scope static
+ object constructed before entering `main'. */
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+ "%{!shared: \
+ %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
+ crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+
+/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
+ the GNU/Linux magical crtend.o file (see crtstuff.c) which
+ provides part of the support for getting C++ file-scope static
+ object constructed before entering `main', followed by a normal
+ GNU/Linux "finalizer" file, `crtn.o'. */
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+ "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
diff --git a/gnu/usr.bin/gcc/config/alpha/osf2or3.h b/gnu/usr.bin/gcc/config/alpha/osf2or3.h
new file mode 100644
index 00000000000..03bc58a61e3
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/alpha/osf2or3.h
@@ -0,0 +1,24 @@
+/* Definitions of target machine for GNU compiler, for DEC Alpha, osf[23].
+ Copyright (C) 1997 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. */
+
+/* In OSF 2 or 3, linking with -lprof1 doesn't require -lpdf. */
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{p:-lprof1} %{pg:-lprof1} %{a:-lprof2} -lc"
diff --git a/gnu/usr.bin/gcc/config/alpha/t-vms b/gnu/usr.bin/gcc/config/alpha/t-vms
new file mode 100644
index 00000000000..12ac24098ce
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/alpha/t-vms
@@ -0,0 +1,6 @@
+# Do not build libgcc1.
+LIBGCC1 =
+CROSS_LIBGCC1 =
+
+LIB2FUNCS_EXTRA = tramp.s
+
diff --git a/gnu/usr.bin/gcc/config/alpha/vms-tramp.asm b/gnu/usr.bin/gcc/config/alpha/vms-tramp.asm
new file mode 100644
index 00000000000..fce9ec539ca
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/alpha/vms-tramp.asm
@@ -0,0 +1,22 @@
+;# New Alpha OpenVMS trampoline
+;#
+ .set noreorder
+ .set volatile
+ .set noat
+ .file 1 "tramp.s"
+.text
+ .align 3
+ .globl __tramp
+ .ent __tramp
+__tramp..en:
+
+.link
+ .align 3
+__tramp:
+ .pdesc __tramp..en,null
+.text
+ ldq $1,24($27)
+ ldq $27,16($27)
+ ldq $28,8($27)
+ jmp $31,($28),0
+ .end __tramp
diff --git a/gnu/usr.bin/gcc/config/alpha/vms.h b/gnu/usr.bin/gcc/config/alpha/vms.h
new file mode 100644
index 00000000000..8e4fd6dc858
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/alpha/vms.h
@@ -0,0 +1,461 @@
+/* Output variables, constants and external declarations, for GNU compiler.
+ Copyright (C) 1996, 1997 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 OPEN_VMS 1
+
+/* This enables certain macros in alpha.h, which will make an indirect
+ reference to an external symbol an invalid address. This needs to be
+ defined before we include alpha.h, since it determines which macros
+ are used for GO_IF_*. */
+
+#define NO_EXTERNAL_INDIRECT_ADDRESS
+
+#include "alpha/alpha.h"
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES \
+"-Dalpha -D__ALPHA -Dvms -DVMS -D__alpha__ -D__alpha -D__vms__ -D__VMS__\
+ -Asystem(vms) -Acpu(alpha) -Amachine(alpha)"
+
+#undef CPP_SPEC
+#define CPP_SPEC "\
+%{mfloat-ieee:-D__IEEE_FLOAT} \
+%{mfloat-vax:-D__G_FLOAT} \
+%{!mfloat-vax:-D__IEEE_FLOAT} \
+%{!.S: -D__LANGUAGE_C__ -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}} \
+%{.S: -D__LANGUAGE_ASSEMBLY__ -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \
+%{.cc: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \
+%{.cxx: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \
+%{.C: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \
+%{.m: -D__LANGUAGE_OBJECTIVE_C__ -D__LANGUAGE_OBJECTIVE_C}"
+
+/* We allow $'s in identifiers unless -ansi is used .. */
+
+#define DOLLARS_IN_IDENTIFIERS 2
+
+/* These match the definitions used in DECCRTL, the VMS C run-time library
+
+#define SIZE_TYPE "unsigned int"
+#define PTRDIFF_TYPE "int"
+*/
+
+/* Use memcpy for structure copying, and so forth. */
+#define TARGET_MEM_FUNCTIONS
+
+/* By default, allow $ to be part of an identifier. */
+#define DOLLARS_IN_IDENTIFIERS 2
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_FP|MASK_FPREGS|MASK_GAS|MASK_OPEN_VMS)
+#undef TARGET_NAME
+#define TARGET_NAME "OpenVMS/Alpha"
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (%s)", TARGET_NAME);
+
+/* The structure return address arrives as an "argument" on VMS. */
+#undef STRUCT_VALUE_REGNUM
+#define STRUCT_VALUE 0
+#undef PCC_STATIC_STRUCT_RETURN
+
+/* no floating emulation. */
+#undef REAL_ARITHMETIC
+
+/* "long" is 32 bits. */
+#undef LONG_TYPE_SIZE
+#define LONG_TYPE_SIZE 32
+
+/* Pointer is 32 bits but the hardware has 64-bit addresses, sign extended. */
+#undef POINTER_SIZE
+#define POINTER_SIZE 32
+#define POINTERS_EXTEND_UNSIGNED 0
+
+#define MAX_OFILE_ALIGNMENT 524288 /* 8 x 2^16 by DEC Ada Test CD40VRA */
+
+#undef FIXED_REGISTERS
+#define FIXED_REGISTERS \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }
+
+#undef CALL_USED_REGISTERS
+#define CALL_USED_REGISTERS \
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
+
+#undef HARD_FRAME_POINTER_REGNUM
+#define HARD_FRAME_POINTER_REGNUM 29
+
+#undef CAN_ELIMINATE
+#define CAN_ELIMINATE(FROM, TO) \
+((TO) != STACK_POINTER_REGNUM || ! alpha_using_fp ())
+
+#undef INITIAL_ELIMINATION_OFFSET
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+{ if ((FROM) == FRAME_POINTER_REGNUM) \
+ (OFFSET) = alpha_sa_size () + alpha_pv_save_size (); \
+ else if ((FROM) == ARG_POINTER_REGNUM) \
+ (OFFSET) = (ALPHA_ROUND (alpha_sa_size () + alpha_pv_save_size () \
+ + get_frame_size () \
+ + current_function_pretend_args_size) \
+ - current_function_pretend_args_size); \
+ if ((TO) == STACK_POINTER_REGNUM) \
+ (OFFSET) += ALPHA_ROUND (current_function_outgoing_args_size); \
+}
+
+/* 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.
+
+ On Alpha/VMS, this is a structure that contains the number of
+ arguments and, for each argument, the datatype of that argument.
+
+ The number of arguments is a number of words of arguments scanned so far.
+ Thus 6 or more means all following args should go on the stack. */
+
+enum avms_arg_type {I64, FF, FD, FG, FS, FT};
+typedef struct {char num_args; enum avms_arg_type atypes[6];} avms_arg_info;
+
+#undef CUMULATIVE_ARGS
+#define CUMULATIVE_ARGS avms_arg_info
+
+/* 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. */
+
+#undef INIT_CUMULATIVE_ARGS
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
+ (CUM).num_args = 0; \
+ (CUM).atypes[0] = (CUM).atypes[1] = (CUM).atypes[2] = I64; \
+ (CUM).atypes[3] = (CUM).atypes[4] = (CUM).atypes[5] = I64;
+
+/* 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.) */
+
+extern enum avms_arg_type alpha_arg_type ();
+
+/* Determine where to put an argument 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 (or VOIDmode for no more args).
+ 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).
+
+ On Alpha the first 6 words of args are normally in registers
+ and the rest are pushed. */
+
+extern struct rtx_def *alpha_arg_info_reg_val ();
+#undef FUNCTION_ARG
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
+((MODE) == VOIDmode ? alpha_arg_info_reg_val (CUM) \
+ : ((CUM.num_args) < 6 && ! MUST_PASS_IN_STACK (MODE, TYPE) \
+ ? gen_rtx(REG, (MODE), \
+ ((CUM).num_args + 16 \
+ + ((TARGET_FPREGS \
+ && (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
+ || GET_MODE_CLASS (MODE) == MODE_FLOAT)) \
+ * 32))) \
+ : 0))
+
+#undef FUNCTION_ARG_ADVANCE
+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
+ if (MUST_PASS_IN_STACK (MODE, TYPE)) \
+ (CUM).num_args += 6; \
+ else \
+ { \
+ if ((CUM).num_args < 6) \
+ (CUM).atypes[(CUM).num_args] = alpha_arg_type (MODE); \
+ \
+ (CUM).num_args += ALPHA_ARG_SIZE (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. */
+
+#undef FUNCTION_ARG_PARTIAL_NREGS
+#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
+((CUM).num_args < 6 && 6 < (CUM).num_args \
+ + ALPHA_ARG_SIZE (MODE, TYPE, NAMED) \
+ ? 6 - (CUM).num_args : 0)
+
+/* Perform any needed actions needed for a function that is receiving a
+ variable number of arguments.
+
+ CUM is as for INIT_CUMULATIVE_ARGS.
+
+ MODE and TYPE are the mode and type of the current parameter.
+
+ PRETEND_SIZE is a variable that should be set to the amount of stack
+ that must be pushed by the prolog to pretend that our caller pushed
+ it.
+
+ Normally, this macro will push all remaining incoming registers on the
+ stack and set PRETEND_SIZE to the length of the registers pushed.
+
+ For VMS, we allocate space for all 6 arg registers plus a count.
+
+ However, if NO registers need to be saved, don't allocate any space.
+ This is not only because we won't need the space, but because AP includes
+ the current_pretend_args_size and we don't want to mess up any
+ ap-relative addresses already made. */
+
+#undef SETUP_INCOMING_VARARGS
+#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
+{ if ((CUM).num_args < 6) \
+ { \
+ if (! (NO_RTL)) \
+ { \
+ emit_move_insn (gen_rtx (REG, DImode, 1), \
+ virtual_incoming_args_rtx); \
+ emit_insn (gen_arg_home ()); \
+ } \
+ \
+ PRETEND_SIZE = 7 * UNITS_PER_WORD; \
+ } \
+}
+
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) \
+{ \
+ alpha_write_verstamp (FILE); \
+ fprintf (FILE, "\t.set noreorder\n"); \
+ fprintf (FILE, "\t.set volatile\n"); \
+ ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
+}
+
+#undef ASM_OUTPUT_FLOAT
+#define ASM_OUTPUT_FLOAT(FILE,VALUE) \
+ { \
+ if (REAL_VALUE_ISINF (VALUE) \
+ || REAL_VALUE_ISNAN (VALUE) \
+ || REAL_VALUE_MINUS_ZERO (VALUE)) \
+ { \
+ long t; \
+ REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
+ fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff); \
+ } \
+ else \
+ { \
+ char str[30]; \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \
+ fprintf (FILE, "\t.%c_floating %s\n", (TARGET_FLOAT_VAX)?'f':'s', str); \
+ } \
+ }
+
+#define LINK_SECTION_ASM_OP ".link"
+#define READONLY_SECTION_ASM_OP ".rdata"
+#define LITERALS_SECTION_ASM_OP ".literals"
+
+#undef EXTRA_SECTIONS
+#define EXTRA_SECTIONS in_link, in_rdata, in_literals
+
+#undef EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS \
+void \
+readonly_section () \
+{ \
+ if (in_section != in_rdata) \
+ { \
+ fprintf (asm_out_file, "%s\n", READONLY_SECTION_ASM_OP); \
+ in_section = in_rdata; \
+ } \
+} \
+void \
+link_section () \
+{ \
+ if (in_section != in_link) \
+ { \
+ fprintf (asm_out_file, "%s\n", LINK_SECTION_ASM_OP); \
+ in_section = in_link; \
+ } \
+} \
+void \
+literals_section () \
+{ \
+ if (in_section != in_literals) \
+ { \
+ fprintf (asm_out_file, "%s\n", LITERALS_SECTION_ASM_OP); \
+ in_section = in_literals; \
+ } \
+}
+
+#undef ASM_OUTPUT_ADDR_DIFF_ELT
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) abort ()
+
+#undef ASM_OUTPUT_ADDR_VEC_ELT
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
+ fprintf (FILE, "\t.quad $%d\n", (VALUE) + 32)
+
+#undef READONLY_DATA_SECTION
+#define READONLY_DATA_SECTION readonly_section
+
+#define ASM_FILE_END(FILE) alpha_write_linkage (FILE);
+
+#undef CASE_VECTOR_MODE
+#define CASE_VECTOR_MODE DImode
+#undef CASE_VECTOR_PC_RELATIVE
+
+#undef ASM_OUTPUT_CASE_LABEL
+#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
+{ ASM_OUTPUT_ALIGN (FILE, 3); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
+
+#define NO_MD_PROTOTYPES
+
+/* Output assembler code for a block containing the constant parts
+ of a trampoline, leaving space for the variable parts.
+
+ The trampoline should set the static chain pointer to value placed
+ into the trampoline and should branch to the specified routine.
+ Note that $27 has been set to the address of the trampoline, so we can
+ use it for addressability of the two data items. Trampolines are always
+ aligned to FUNCTION_BOUNDARY, which is 64 bits. */
+
+#undef TRAMPOLINE_TEMPLATE
+#define TRAMPOLINE_TEMPLATE(FILE) \
+{ \
+ fprintf (FILE, "\t.quad 0\n"); \
+ fprintf (FILE, "\t.linkage __tramp\n"); \
+ fprintf (FILE, "\t.quad 0\n"); \
+}
+
+/* Length in units of the trampoline for entering a nested function. */
+
+#undef TRAMPOLINE_SIZE
+#define TRAMPOLINE_SIZE 32
+
+/* 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. */
+
+#undef INITIALIZE_TRAMPOLINE
+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
+{ \
+ emit_move_insn (gen_rtx (MEM, Pmode, \
+ memory_address (Pmode, \
+ plus_constant ((TRAMP), 16))), \
+ (FNADDR)); \
+ emit_move_insn (gen_rtx (MEM, Pmode, \
+ memory_address (Pmode, \
+ plus_constant ((TRAMP), 24))), \
+ (CXT)); \
+}
+
+#undef TRANSFER_FROM_TRAMPOLINE
+
+#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, NAME, ARGS) \
+ (vms_valid_decl_attribute_p (DECL, ATTRIBUTES, NAME, ARGS))
+extern int vms_valid_decl_attribute_p ();
+
+#undef SDB_DEBUGGING_INFO
+#undef MIPS_DEBUGGING_INFO
+#undef DBX_DEBUGGING_INFO
+
+#define DWARF2_DEBUGGING_INFO
+
+/* This is how to output an assembler line
+ that says to advance the location counter
+ to a multiple of 2**LOG bytes. */
+
+#undef ASM_OUTPUT_ALIGN
+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
+ fprintf (FILE, "\t.align %d\n", LOG);
+
+#define UNALIGNED_SHORT_ASM_OP ".word"
+#define UNALIGNED_INT_ASM_OP ".long"
+#define UNALIGNED_DOUBLE_INT_ASM_OP ".quad"
+
+#undef ASM_OUTPUT_ALIGNED_COMMON
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
+do { \
+ fprintf ((FILE), "\t.comm\t"); \
+ assemble_name ((FILE), (NAME)); \
+ fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
+} while (0)
+
+#define ASM_OUTPUT_SECTION(FILE,SECTION) \
+ (strcmp (SECTION, ".text") == 0) \
+ ? text_section () \
+ : named_section (NULL_TREE, SECTION, 0), \
+ ASM_OUTPUT_ALIGN (FILE, 0) \
+
+#define ASM_OUTPUT_SECTION_NAME(FILE,DECL,NAME,RELOC) \
+ do \
+ { \
+ char *flags; \
+ int ovr = 0; \
+ if (DECL && DECL_MACHINE_ATTRIBUTES (DECL) \
+ && lookup_attribute \
+ ("overlaid", DECL_MACHINE_ATTRIBUTES (DECL))) \
+ flags = ",OVR", ovr = 1; \
+ else if (strncmp (NAME,".debug", 6) == 0) \
+ flags = ",NOWRT"; \
+ else \
+ flags = ""; \
+ fputc ('\n', (FILE)); \
+ fprintf (FILE, ".section\t%s%s\n", NAME, flags); \
+ if (ovr) \
+ (NAME) = ""; \
+ } while (0)
+
+#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
+ do { literals_section(); \
+ fprintf ((FILE), "\t"); \
+ assemble_name (FILE, LABEL1); \
+ fprintf (FILE, " = "); \
+ assemble_name (FILE, LABEL2); \
+ fprintf (FILE, "\n"); \
+ } while (0)
+
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+
+#undef ASM_FORMAT_PRIVATE_NAME
+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
+( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 12), \
+ sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
+
+#undef ASM_SPEC
+#undef ASM_FINAL_SPEC
+#undef LINK_SPEC
+#undef STARTFILE_SPEC
+#define ASM_SPEC "-nocpp %{pg}"
+#define LINK_SPEC "%{g3:-g3} %{g0:-g0} %{shared:-shared} %{v:-v}"
+
+/* Define the names of the division and modulus functions. */
+#define DIVSI3_LIBCALL "ots$div_i"
+#define DIVDI3_LIBCALL "ots$div_l"
+#define UDIVSI3_LIBCALL "ots$div_ui"
+#define UDIVDI3_LIBCALL "ots$div_ul"
+#define MODSI3_LIBCALL "ots$rem_i"
+#define MODDI3_LIBCALL "ots$rem_l"
+#define UMODSI3_LIBCALL "ots$rem_ui"
+#define UMODDI3_LIBCALL "ots$rem_ul"
diff --git a/gnu/usr.bin/gcc/config/alpha/xm-vms.h b/gnu/usr.bin/gcc/config/alpha/xm-vms.h
new file mode 100644
index 00000000000..6b7dad578f1
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/alpha/xm-vms.h
@@ -0,0 +1,82 @@
+/* Configuration for GNU C-compiler for openVMS/Alpha.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Klaus Kaempf (kkaempf@progis.de).
+
+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. */
+
+/* If compiling with DECC, need to fix problem with <stdio.h>
+ which defines a macro called FILE_TYPE that breaks "tree.h".
+ Fortunately it uses #ifndef to suppress multiple inclusions.
+ Three possible cases:
+ 1) <stdio.h> has already been included -- ours will be no-op;
+ 2) <stdio.h> will be included after us -- "theirs" will be no-op;
+ 3) <stdio.h> isn't needed -- including it here shouldn't hurt.
+ In all three cases, the problem macro will be removed here. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef __DECC
+#undef FILE_TYPE
+#endif
+
+#undef HOST_BITS_PER_LONG
+#define HOST_BITS_PER_LONG 32
+
+#define HOST_WIDE_INT long long
+#define HOST_BITS_PER_WIDE_INT 64
+
+#undef SUCCESS_EXIT_CODE
+#define SUCCESS_EXIT_CODE 1
+#undef FATAL_EXIT_CODE
+#define FATAL_EXIT_CODE (44 | 0x10000000) /* Abort, and no DCL message. */
+
+/* A couple of conditionals for execution machine are controlled here. */
+#ifndef VMS
+#define VMS
+#endif
+
+/* Define a local equivalent (sort of) for unlink */
+#define unlink remove
+
+#define NEED_ATEXIT
+#define HAVE_VPRINTF
+#define HAVE_PUTENV
+#define HAVE_STRERROR
+
+#define NO_SYS_PARAMS_H /* Don't have <sys/params.h> */
+#define NO_STAB_H /* Don't have <stab.h> */
+#define USE_C_ALLOCA /* Using alloca.c */
+
+#define HAVE_FCNTL_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_UNISTD_H 1
+#define HAVE_STRING_H 1
+#define HAVE_LIMITS_H 1
+#define HAVE_STDDEF_H 1
+#define HAVE_TIME_H 1
+#define STDC_HEADERS 1
+
+#if __STDC__
+extern void *alloca (size_t);
+#else
+extern char *alloca (unsigned int);
+#endif
+
+#define OBJECT_SUFFIX ".obj"
+#define EXECUTABLE_SUFFIX ".exe"
diff --git a/gnu/usr.bin/gcc/config/arc/arc.c b/gnu/usr.bin/gcc/config/arc/arc.c
new file mode 100644
index 00000000000..7272cc927c8
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arc/arc.c
@@ -0,0 +1,2212 @@
+/* Subroutines used for code generation on the Argonaut ARC cpu.
+ Copyright (C) 1994, 1995, 1997 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 an old port, and is undoubtedly suffering from bit rot. */
+
+#include <stdio.h>
+#include "config.h"
+#include "tree.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 "flags.h"
+#include "expr.h"
+#include "recog.h"
+
+/* Which cpu we're compiling for (NULL(=base), ???). */
+char *arc_cpu_string;
+int arc_cpu_type;
+
+/* Name of mangle string to add to symbols to separate code compiled for each
+ cpu (or NULL). */
+char *arc_mangle_cpu;
+
+/* Save the operands last given to a compare for use when we
+ generate a scc or bcc insn. */
+rtx arc_compare_op0, arc_compare_op1;
+
+/* Name of text, data, and rodata sections, as specified on command line.
+ Selected by -m{text,data,rodata} flags. */
+char *arc_text_string = ARC_DEFAULT_TEXT_SECTION;
+char *arc_data_string = ARC_DEFAULT_DATA_SECTION;
+char *arc_rodata_string = ARC_DEFAULT_RODATA_SECTION;
+
+/* Name of text, data, and rodata sections used in varasm.c. */
+char *arc_text_section;
+char *arc_data_section;
+char *arc_rodata_section;
+
+/* Array of valid operand punctuation characters. */
+char arc_punct_chars[256];
+
+/* Variables used by arc_final_prescan_insn to implement conditional
+ execution. */
+static int arc_ccfsm_state;
+static int arc_ccfsm_current_cc;
+static rtx arc_ccfsm_target_insn;
+static int arc_ccfsm_target_label;
+
+/* The maximum number of insns skipped which will be conditionalised if
+ possible. */
+#define MAX_INSNS_SKIPPED 3
+
+/* A nop is needed between a 4 byte insn that sets the condition codes and
+ a branch that uses them (the same isn't true for an 8 byte insn that sets
+ the condition codes). Set by arc_final_prescan_insn. Used by
+ arc_print_operand. */
+static int last_insn_set_cc_p;
+static int current_insn_set_cc_p;
+static void record_cc_ref ();
+
+void arc_init_reg_tables ();
+
+/* Called by OVERRIDE_OPTIONS to initialize various things. */
+
+void
+arc_init (void)
+{
+ if (arc_cpu_string == 0
+ || !strcmp (arc_cpu_string, "base"))
+ {
+ /* Ensure we have a printable value for the .cpu pseudo-op. */
+ arc_cpu_string = "base";
+ arc_cpu_type = 0;
+ arc_mangle_cpu = NULL;
+ }
+ else if (ARC_EXTENSION_CPU (arc_cpu_string))
+ ; /* nothing to do */
+ else
+ {
+ error ("bad value (%s) for -mcpu switch", arc_cpu_string);
+ arc_cpu_string = "base";
+ arc_cpu_type = 0;
+ arc_mangle_cpu = NULL;
+ }
+
+ /* Set the pseudo-ops for the various standard sections. */
+ arc_text_section = xmalloc (strlen (arc_text_string) + sizeof (ARC_SECTION_FORMAT) + 1);
+ sprintf (arc_text_section, ARC_SECTION_FORMAT, arc_text_string);
+ arc_data_section = xmalloc (strlen (arc_data_string) + sizeof (ARC_SECTION_FORMAT) + 1);
+ sprintf (arc_data_section, ARC_SECTION_FORMAT, arc_data_string);
+ arc_rodata_section = xmalloc (strlen (arc_rodata_string) + sizeof (ARC_SECTION_FORMAT) + 1);
+ sprintf (arc_rodata_section, ARC_SECTION_FORMAT, arc_rodata_string);
+
+ arc_init_reg_tables ();
+
+ /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
+ memset (arc_punct_chars, 0, sizeof (arc_punct_chars));
+ arc_punct_chars['#'] = 1;
+ arc_punct_chars['*'] = 1;
+ arc_punct_chars['?'] = 1;
+ arc_punct_chars['!'] = 1;
+ arc_punct_chars['~'] = 1;
+}
+
+/* The condition codes of the ARC, and the inverse function. */
+static char *arc_condition_codes[] =
+{
+ "al", 0, "eq", "ne", "p", "n", "c", "nc", "v", "nv",
+ "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
+};
+
+#define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
+
+/* Returns the index of the ARC condition code string in
+ `arc_condition_codes'. COMPARISON should be an rtx like
+ `(eq (...) (...))'. */
+
+static int
+get_arc_condition_code (comparison)
+ rtx comparison;
+{
+ switch (GET_CODE (comparison))
+ {
+ case EQ : return 2;
+ case NE : return 3;
+ case GT : return 10;
+ case LE : return 11;
+ case GE : return 12;
+ case LT : return 13;
+ case GTU : return 14;
+ case LEU : return 15;
+ case LTU : return 6;
+ case GEU : return 7;
+ default : abort ();
+ }
+ /*NOTREACHED*/
+ return (42);
+}
+
+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
+ return the mode to be used for the comparison. */
+
+enum machine_mode
+arc_select_cc_mode (op, x, y)
+ enum rtx_code op;
+ rtx x, y;
+{
+ switch (op)
+ {
+ case EQ :
+ case NE :
+ return CCZNmode;
+ default :
+ switch (GET_CODE (x))
+ {
+ case AND :
+ case IOR :
+ case XOR :
+ case SIGN_EXTEND :
+ case ZERO_EXTEND :
+ return CCZNmode;
+ case ASHIFT :
+ case ASHIFTRT :
+ case LSHIFTRT :
+ return CCZNCmode;
+ }
+ }
+ return CCmode;
+}
+
+/* Vectors to keep interesting information about registers where it can easily
+ be got. We use to use the actual mode value as the bit number, but there
+ is (or may be) more than 32 modes now. Instead we use two tables: one
+ indexed by hard register number, and one indexed by mode. */
+
+/* The purpose of arc_mode_class is to shrink the range of modes so that
+ they all fit (as bit numbers) in a 32 bit word (again). Each real mode is
+ mapped into one arc_mode_class mode. */
+
+enum arc_mode_class {
+ C_MODE,
+ S_MODE, D_MODE, T_MODE, O_MODE,
+ SF_MODE, DF_MODE, TF_MODE, OF_MODE
+};
+
+/* Modes for condition codes. */
+#define C_MODES (1 << (int) C_MODE)
+
+/* Modes for single-word and smaller quantities. */
+#define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
+
+/* Modes for double-word and smaller quantities. */
+#define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
+
+/* Modes for quad-word and smaller quantities. */
+#define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
+
+/* Value is 1 if register/mode pair is acceptable on arc. */
+
+unsigned int arc_hard_regno_mode_ok[] = {
+ T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
+ T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
+ T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES,
+ D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
+
+ /* ??? Leave these as S_MODES for now. */
+ S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
+ S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
+ S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
+ S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES
+};
+
+unsigned int arc_mode_class [NUM_MACHINE_MODES];
+
+enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
+
+void
+arc_init_reg_tables ()
+{
+ int i;
+
+ for (i = 0; i < NUM_MACHINE_MODES; i++)
+ {
+ switch (GET_MODE_CLASS (i))
+ {
+ case MODE_INT:
+ case MODE_PARTIAL_INT:
+ case MODE_COMPLEX_INT:
+ if (GET_MODE_SIZE (i) <= 4)
+ arc_mode_class[i] = 1 << (int) S_MODE;
+ else if (GET_MODE_SIZE (i) == 8)
+ arc_mode_class[i] = 1 << (int) D_MODE;
+ else if (GET_MODE_SIZE (i) == 16)
+ arc_mode_class[i] = 1 << (int) T_MODE;
+ else if (GET_MODE_SIZE (i) == 32)
+ arc_mode_class[i] = 1 << (int) O_MODE;
+ else
+ arc_mode_class[i] = 0;
+ break;
+ case MODE_FLOAT:
+ case MODE_COMPLEX_FLOAT:
+ if (GET_MODE_SIZE (i) <= 4)
+ arc_mode_class[i] = 1 << (int) SF_MODE;
+ else if (GET_MODE_SIZE (i) == 8)
+ arc_mode_class[i] = 1 << (int) DF_MODE;
+ else if (GET_MODE_SIZE (i) == 16)
+ arc_mode_class[i] = 1 << (int) TF_MODE;
+ else if (GET_MODE_SIZE (i) == 32)
+ arc_mode_class[i] = 1 << (int) OF_MODE;
+ else
+ arc_mode_class[i] = 0;
+ break;
+ case MODE_CC:
+ default:
+ /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
+ we must explicitly check for them here. */
+ if (i == (int) CCmode || i == (int) CCZNmode || i == (int) CCZNCmode)
+ arc_mode_class[i] = 1 << (int) C_MODE;
+ else
+ arc_mode_class[i] = 0;
+ break;
+ }
+ }
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ {
+ if (i < 60)
+ arc_regno_reg_class[i] = GENERAL_REGS;
+ else if (i == 60)
+ arc_regno_reg_class[i] = LPCOUNT_REG;
+ else if (i == 61)
+ arc_regno_reg_class[i] = NO_REGS /* CC_REG: must be NO_REGS */;
+ else
+ arc_regno_reg_class[i] = NO_REGS;
+ }
+}
+
+/* ARC specific attribute support.
+
+ The ARC has these attributes:
+ interrupt - for interrupt functions
+*/
+
+/* Return nonzero if IDENTIFIER is a valid decl attribute. */
+
+int
+arc_valid_machine_decl_attribute (type, attributes, identifier, args)
+ tree type;
+ tree attributes;
+ tree identifier;
+ tree args;
+{
+ if (identifier == get_identifier ("__interrupt__")
+ && list_length (args) == 1
+ && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
+ {
+ tree value = TREE_VALUE (args);
+
+ if (!strcmp (TREE_STRING_POINTER (value), "ilink1")
+ || !strcmp (TREE_STRING_POINTER (value), "ilink2"))
+ return 1;
+ }
+ return 0;
+}
+
+/* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
+ and two if they are nearly compatible (which causes a warning to be
+ generated). */
+
+int
+arc_comp_type_attributes (type1, type2)
+ tree type1, type2;
+{
+ return 1;
+}
+
+/* Set the default attributes for TYPE. */
+
+void
+arc_set_default_type_attributes (type)
+ tree type;
+{
+}
+
+/* Acceptable arguments to the call insn. */
+
+int
+call_address_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ return (symbolic_operand (op, mode)
+ || (GET_CODE (op) == CONST_INT && LEGITIMATE_CONSTANT_P (op))
+ || (GET_CODE (op) == REG));
+}
+
+int
+call_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != MEM)
+ return 0;
+ op = XEXP (op, 0);
+ return call_address_operand (op, mode);
+}
+
+/* Returns 1 if OP is a symbol reference. */
+
+int
+symbolic_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ switch (GET_CODE (op))
+ {
+ case SYMBOL_REF:
+ case LABEL_REF:
+ case CONST :
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* Return truth value of statement that OP is a symbolic memory
+ operand of mode MODE. */
+
+int
+symbolic_memory_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+ if (GET_CODE (op) != MEM)
+ return 0;
+ op = XEXP (op, 0);
+ return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
+ || GET_CODE (op) == LABEL_REF);
+}
+
+/* Return true if OP is a short immediate (shimm) value. */
+
+int
+short_immediate_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ return SMALL_INT (INTVAL (op));
+}
+
+/* Return true if OP will require a long immediate (limm) value.
+ This is currently only used when calculating length attributes. */
+
+int
+long_immediate_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ switch (GET_CODE (op))
+ {
+ case SYMBOL_REF :
+ case LABEL_REF :
+ case CONST :
+ return 1;
+ case CONST_INT :
+ return !SMALL_INT (INTVAL (op));
+ case CONST_DOUBLE :
+ /* These can happen because large unsigned 32 bit constants are
+ represented this way (the multiplication patterns can cause these
+ to be generated). They also occur for SFmode values. */
+ return 1;
+ }
+ return 0;
+}
+
+/* Return true if OP is a MEM that when used as a load or store address will
+ require an 8 byte insn.
+ Load and store instructions don't allow the same possibilities but they're
+ similar enough that this one function will do.
+ This is currently only used when calculating length attributes. */
+
+int
+long_immediate_loadstore_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != MEM)
+ return 0;
+
+ op = XEXP (op, 0);
+ switch (GET_CODE (op))
+ {
+ case SYMBOL_REF :
+ case LABEL_REF :
+ case CONST :
+ return 1;
+ case CONST_INT :
+ /* This must be handled as "st c,[limm]". Ditto for load.
+ Technically, the assembler could translate some possibilities to
+ "st c,[limm/2 + limm/2]" if limm/2 will fit in a shimm, but we don't
+ assume that it does. */
+ return 1;
+ case CONST_DOUBLE :
+ /* These can happen because large unsigned 32 bit constants are
+ represented this way (the multiplication patterns can cause these
+ to be generated). They also occur for SFmode values. */
+ return 1;
+ case REG :
+ return 0;
+ case PLUS :
+ if (GET_CODE (XEXP (op, 1)) == CONST_INT
+ && !SMALL_INT (INTVAL (XEXP (op, 1))))
+ return 1;
+ return 0;
+ }
+ return 0;
+}
+
+/* Return true if OP is an acceptable argument for a single word
+ move source. */
+
+int
+move_src_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ switch (GET_CODE (op))
+ {
+ case SYMBOL_REF :
+ case LABEL_REF :
+ case CONST :
+ return 1;
+ case CONST_INT :
+ return (LARGE_INT (INTVAL (op)));
+ case CONST_DOUBLE :
+ /* We can handle DImode integer constants in SImode if the value
+ (signed or unsigned) will fit in 32 bits. This is needed because
+ large unsigned 32 bit constants are represented as CONST_DOUBLEs. */
+ if (mode == SImode)
+ return arc_double_limm_p (op);
+ /* We can handle 32 bit floating point constants. */
+ if (mode == SFmode)
+ return GET_MODE (op) == SFmode;
+ return 0;
+ case REG :
+ return register_operand (op, mode);
+ case SUBREG :
+ /* (subreg (mem ...) ...) can occur here if the inner part was once a
+ pseudo-reg and is now a stack slot. */
+ if (GET_CODE (SUBREG_REG (op)) == MEM)
+ return address_operand (XEXP (SUBREG_REG (op), 0), mode);
+ else
+ return register_operand (op, mode);
+ case MEM :
+ return address_operand (XEXP (op, 0), mode);
+ default :
+ return 0;
+ }
+}
+
+/* Return true if OP is an acceptable argument for a double word
+ move source. */
+
+int
+move_double_src_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ switch (GET_CODE (op))
+ {
+ case REG :
+ return register_operand (op, mode);
+ case SUBREG :
+ /* (subreg (mem ...) ...) can occur here if the inner part was once a
+ pseudo-reg and is now a stack slot. */
+ if (GET_CODE (SUBREG_REG (op)) == MEM)
+ return move_double_src_operand (SUBREG_REG (op), mode);
+ else
+ return register_operand (op, mode);
+ case MEM :
+ /* Disallow auto inc/dec for now. */
+ if (GET_CODE (XEXP (op, 0)) == PRE_DEC
+ || GET_CODE (XEXP (op, 0)) == PRE_INC)
+ return 0;
+ return address_operand (XEXP (op, 0), mode);
+ case CONST_INT :
+ case CONST_DOUBLE :
+ return 1;
+ default :
+ return 0;
+ }
+}
+
+/* Return true if OP is an acceptable argument for a move destination. */
+
+int
+move_dest_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ switch (GET_CODE (op))
+ {
+ case REG :
+ return register_operand (op, mode);
+ case SUBREG :
+ /* (subreg (mem ...) ...) can occur here if the inner part was once a
+ pseudo-reg and is now a stack slot. */
+ if (GET_CODE (SUBREG_REG (op)) == MEM)
+ return address_operand (XEXP (SUBREG_REG (op), 0), mode);
+ else
+ return register_operand (op, mode);
+ case MEM :
+ return address_operand (XEXP (op, 0), mode);
+ default :
+ return 0;
+ }
+}
+
+/* Return true if OP is valid load with update operand. */
+
+int
+load_update_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != MEM
+ || GET_MODE (op) != mode)
+ return 0;
+ op = XEXP (op, 0);
+ if (GET_CODE (op) != PLUS
+ || GET_MODE (op) != Pmode
+ || !register_operand (XEXP (op, 0), Pmode)
+ || !nonmemory_operand (XEXP (op, 1), Pmode))
+ return 0;
+ return 1;
+}
+
+/* Return true if OP is valid store with update operand. */
+
+int
+store_update_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != MEM
+ || GET_MODE (op) != mode)
+ return 0;
+ op = XEXP (op, 0);
+ if (GET_CODE (op) != PLUS
+ || GET_MODE (op) != Pmode
+ || !register_operand (XEXP (op, 0), Pmode)
+ || !(GET_CODE (XEXP (op, 1)) == CONST_INT
+ && SMALL_INT (INTVAL (XEXP (op, 1)))))
+ return 0;
+ return 1;
+}
+
+/* Return true if OP is a non-volatile non-immediate operand.
+ Volatile memory refs require a special "cache-bypass" instruction
+ and only the standard movXX patterns are set up to handle them. */
+
+int
+nonvol_nonimm_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == MEM && MEM_VOLATILE_P (op))
+ return 0;
+ return nonimmediate_operand (op, mode);
+}
+
+/* Accept integer operands in the range -0x80000000..0x7fffffff. We have
+ to check the range carefully since this predicate is used in DImode
+ contexts. */
+
+int
+const_sint32_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ /* All allowed constants will fit a CONST_INT. */
+ return (GET_CODE (op) == CONST_INT
+ && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
+}
+
+/* Accept integer operands in the range 0..0xffffffff. We have to check the
+ range carefully since this predicate is used in DImode contexts. Also, we
+ need some extra crud to make it work when hosted on 64-bit machines. */
+
+int
+const_uint32_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+#if HOST_BITS_PER_WIDE_INT > 32
+ /* All allowed constants will fit a CONST_INT. */
+ return (GET_CODE (op) == CONST_INT
+ && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
+#else
+ return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0)
+ || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
+#endif
+}
+
+/* Return 1 if OP is a comparison operator valid for the mode of CC.
+ This allows the use of MATCH_OPERATOR to recognize all the branch insns.
+
+ Some insns only set a few bits in the condition code. So only allow those
+ comparisons that use the bits that are valid. */
+
+int
+proper_comparison_operator (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ enum rtx_code code = GET_CODE (op);
+
+ if (GET_RTX_CLASS (code) != '<')
+ return 0;
+
+ if (GET_MODE (XEXP (op, 0)) == CCZNmode)
+ return (code == EQ || code == NE);
+ if (GET_MODE (XEXP (op, 0)) == CCZNCmode)
+ return (code == EQ || code == NE
+ || code == LTU || code == GEU || code == GTU || code == LEU);
+ return 1;
+}
+
+/* Misc. utilities. */
+
+/* X and Y are two things to compare using CODE. Emit the compare insn and
+ return the rtx for the cc reg in the proper mode. */
+
+rtx
+gen_compare_reg (code, x, y)
+ enum rtx_code code;
+ rtx x, y;
+{
+ enum machine_mode mode = SELECT_CC_MODE (code, x, y);
+ rtx cc_reg;
+
+ cc_reg = gen_rtx (REG, mode, 61);
+
+ emit_insn (gen_rtx (SET, VOIDmode, cc_reg,
+ gen_rtx (COMPARE, mode, x, y)));
+
+ return cc_reg;
+}
+
+/* Return 1 if VALUE, a const_double, will fit in a limm (4 byte number).
+ We assume the value can be either signed or unsigned. */
+
+int
+arc_double_limm_p (value)
+ rtx value;
+{
+ HOST_WIDE_INT low, high;
+
+ if (GET_CODE (value) != CONST_DOUBLE)
+ abort ();
+
+ low = CONST_DOUBLE_LOW (value);
+ high = CONST_DOUBLE_HIGH (value);
+
+ if (low & 0x80000000)
+ {
+ return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0)
+ || (((low & - (unsigned HOST_WIDE_INT) 0x80000000)
+ == - (unsigned HOST_WIDE_INT) 0x80000000)
+ && high == -1));
+ }
+ else
+ {
+ return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
+ }
+}
+
+/* Do any needed setup for a variadic function. For the ARC, we must
+ create a register parameter block, and then copy any anonymous arguments
+ in registers to memory.
+
+ CUM has not been updated for the last named argument which has type TYPE
+ and mode MODE, and we rely on this fact.
+
+ We do things a little weird here. We're supposed to only allocate space
+ for the anonymous arguments. However we need to keep the stack eight byte
+ aligned. So we round the space up if necessary, and leave it to va-arc.h
+ to compensate. */
+
+void
+arc_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
+ CUMULATIVE_ARGS *cum;
+ enum machine_mode mode;
+ tree type;
+ int *pretend_size;
+ int no_rtl;
+{
+ int first_anon_arg;
+
+ /* All BLKmode values are passed by reference. */
+ if (mode == BLKmode)
+ abort ();
+
+ /* We must treat `__builtin_va_alist' as an anonymous arg. */
+ if (current_function_varargs)
+ first_anon_arg = *cum;
+ else
+ first_anon_arg = *cum + ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
+ / UNITS_PER_WORD);
+
+ if (first_anon_arg < MAX_ARC_PARM_REGS && !no_rtl)
+ {
+ /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
+ int first_reg_offset = first_anon_arg;
+ /* Size in words to "pretend" allocate. */
+ int size = MAX_ARC_PARM_REGS - first_reg_offset;
+ /* Extra slop to keep stack eight byte aligned. */
+ int align_slop = size & 1;
+ rtx regblock;
+
+ regblock = gen_rtx (MEM, BLKmode,
+ plus_constant (arg_pointer_rtx,
+ FIRST_PARM_OFFSET (0)
+ + align_slop * UNITS_PER_WORD));
+ move_block_from_reg (first_reg_offset, regblock,
+ MAX_ARC_PARM_REGS - first_reg_offset,
+ ((MAX_ARC_PARM_REGS - first_reg_offset)
+ * UNITS_PER_WORD));
+
+ *pretend_size = ((MAX_ARC_PARM_REGS - first_reg_offset + align_slop)
+ * UNITS_PER_WORD);
+ }
+}
+
+/* Cost functions. */
+
+/* Provide the costs of an addressing mode that contains ADDR.
+ If ADDR is not a valid address, its cost is irrelevant. */
+
+int
+arc_address_cost (addr)
+ rtx addr;
+{
+ switch (GET_CODE (addr))
+ {
+ case REG :
+ /* This is handled in the macro that calls us.
+ It's here for documentation. */
+ return 1;
+
+ case LABEL_REF :
+ case SYMBOL_REF :
+ case CONST :
+ return 2;
+
+ case PLUS :
+ {
+ register rtx plus0 = XEXP (addr, 0);
+ register rtx plus1 = XEXP (addr, 1);
+
+ if (GET_CODE (plus0) != REG)
+ break;
+
+ switch (GET_CODE (plus1))
+ {
+ case CONST_INT :
+ return SMALL_INT (plus1) ? 1 : 2;
+ case CONST :
+ case SYMBOL_REF :
+ case LABEL_REF :
+ return 2;
+ default:
+ break;
+ }
+ break;
+ }
+ }
+
+ return 4;
+}
+
+/* Function prologue/epilogue handlers. */
+
+/* ARC stack frames look like:
+
+ Before call After call
+ +-----------------------+ +-----------------------+
+ | | | |
+ high | local variables, | | local variables, |
+ mem | reg save area, etc. | | reg save area, etc. |
+ | | | |
+ +-----------------------+ +-----------------------+
+ | | | |
+ | arguments on stack. | | arguments on stack. |
+ | | | |
+ SP+16->+-----------------------+FP+48->+-----------------------+
+ | 4 word save area for | | reg parm save area, |
+ | return addr, prev %fp | | only created for |
+ SP+0->+-----------------------+ | variable argument |
+ | functions |
+ FP+16->+-----------------------+
+ | 4 word save area for |
+ | return addr, prev %fp |
+ FP+0->+-----------------------+
+ | |
+ | local variables |
+ | |
+ +-----------------------+
+ | |
+ | register save area |
+ | |
+ +-----------------------+
+ | |
+ | alloca allocations |
+ | |
+ +-----------------------+
+ | |
+ | arguments on stack |
+ | |
+ SP+16->+-----------------------+
+ low | 4 word save area for |
+ memory | return addr, prev %fp |
+ SP+0->+-----------------------+
+
+Notes:
+1) The "reg parm save area" does not exist for non variable argument fns.
+ The "reg parm save area" can be eliminated completely if we created our
+ own va-arc.h, but that has tradeoffs as well (so it's not done). */
+
+/* Structure to be filled in by arc_compute_frame_size with register
+ save masks, and offsets for the current function. */
+struct arc_frame_info
+{
+ unsigned int total_size; /* # bytes that the entire frame takes up. */
+ unsigned int extra_size; /* # bytes of extra stuff. */
+ unsigned int pretend_size; /* # bytes we push and pretend caller did. */
+ unsigned int args_size; /* # bytes that outgoing arguments take up. */
+ unsigned int reg_size; /* # bytes needed to store regs. */
+ unsigned int var_size; /* # bytes that variables take up. */
+ unsigned int reg_offset; /* Offset from new sp to store regs. */
+ unsigned int gmask; /* Mask of saved gp registers. */
+ int initialized; /* Nonzero if frame size already calculated. */
+};
+
+/* Current frame information calculated by arc_compute_frame_size. */
+static struct arc_frame_info current_frame_info;
+
+/* Zero structure to initialize current_frame_info. */
+static struct arc_frame_info zero_frame_info;
+
+/* Type of function DECL.
+
+ The result is cached. To reset the cache at the end of a function,
+ call with DECL = NULL_TREE. */
+
+enum arc_function_type
+arc_compute_function_type (decl)
+ tree decl;
+{
+ tree a;
+ /* Cached value. */
+ static enum arc_function_type fn_type = ARC_FUNCTION_UNKNOWN;
+ /* Last function we were called for. */
+ static tree last_fn = NULL_TREE;
+
+ /* Resetting the cached value? */
+ if (decl == NULL_TREE)
+ {
+ fn_type = ARC_FUNCTION_UNKNOWN;
+ last_fn = NULL_TREE;
+ return fn_type;
+ }
+
+ if (decl == last_fn && fn_type != ARC_FUNCTION_UNKNOWN)
+ return fn_type;
+
+ /* Assume we have a normal function (not an interrupt handler). */
+ fn_type = ARC_FUNCTION_NORMAL;
+
+ /* Now see if this is an interrupt handler. */
+ for (a = DECL_MACHINE_ATTRIBUTES (current_function_decl);
+ a;
+ a = TREE_CHAIN (a))
+ {
+ tree name = TREE_PURPOSE (a), args = TREE_VALUE (a);
+
+ if (name == get_identifier ("__interrupt__")
+ && list_length (args) == 1
+ && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
+ {
+ tree value = TREE_VALUE (args);
+
+ if (!strcmp (TREE_STRING_POINTER (value), "ilink1"))
+ fn_type = ARC_FUNCTION_ILINK1;
+ else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
+ fn_type = ARC_FUNCTION_ILINK2;
+ else
+ abort ();
+ break;
+ }
+ }
+
+ last_fn = decl;
+ return fn_type;
+}
+
+#define ILINK1_REGNUM 29
+#define ILINK2_REGNUM 30
+#define RETURN_ADDR_REGNUM 31
+#define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
+#define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
+
+/* Tell prologue and epilogue if register REGNO should be saved / restored.
+ The return address and frame pointer are treated separately.
+ Don't consider them here. */
+#define MUST_SAVE_REGISTER(regno, interrupt_p) \
+((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \
+ && (regs_ever_live[regno] && (!call_used_regs[regno] || interrupt_p)))
+
+#define MUST_SAVE_RETURN_ADDR (regs_ever_live[RETURN_ADDR_REGNUM])
+
+/* Return the bytes needed to compute the frame pointer from the current
+ stack pointer.
+
+ SIZE is the size needed for local variables. */
+
+unsigned int
+arc_compute_frame_size (size)
+ int size; /* # of var. bytes allocated. */
+{
+ int regno;
+ unsigned int total_size, var_size, args_size, pretend_size, extra_size;
+ unsigned int reg_size, reg_offset;
+ unsigned int gmask;
+ enum arc_function_type fn_type;
+ int interrupt_p;
+
+ var_size = size;
+ args_size = current_function_outgoing_args_size;
+ pretend_size = current_function_pretend_args_size;
+ extra_size = FIRST_PARM_OFFSET (0);
+ total_size = extra_size + pretend_size + args_size + var_size;
+ reg_offset = FIRST_PARM_OFFSET(0) + current_function_outgoing_args_size;
+ reg_size = 0;
+ gmask = 0;
+
+ /* See if this is an interrupt handler. Call used registers must be saved
+ for them too. */
+ fn_type = arc_compute_function_type (current_function_decl);
+ interrupt_p = ARC_INTERRUPT_P (fn_type);
+
+ /* Calculate space needed for registers.
+ ??? We ignore the extension registers for now. */
+
+ for (regno = 0; regno <= 31; regno++)
+ {
+ if (MUST_SAVE_REGISTER (regno, interrupt_p))
+ {
+ reg_size += UNITS_PER_WORD;
+ gmask |= 1 << regno;
+ }
+ }
+
+ total_size += reg_size;
+
+ /* If the only space to allocate is the fp/blink save area this is an
+ empty frame. However, if we'll be making a function call we need to
+ allocate a stack frame for our callee's fp/blink save area. */
+ if (total_size == extra_size
+ && !MUST_SAVE_RETURN_ADDR)
+ total_size = extra_size = 0;
+
+ total_size = ARC_STACK_ALIGN (total_size);
+
+ /* Save computed information. */
+ current_frame_info.total_size = total_size;
+ current_frame_info.extra_size = extra_size;
+ current_frame_info.pretend_size = pretend_size;
+ current_frame_info.var_size = var_size;
+ current_frame_info.args_size = args_size;
+ current_frame_info.reg_size = reg_size;
+ current_frame_info.reg_offset = reg_offset;
+ current_frame_info.gmask = gmask;
+ current_frame_info.initialized = reload_completed;
+
+ /* Ok, we're done. */
+ return total_size;
+}
+
+/* Common code to save/restore registers. */
+
+void
+arc_save_restore (file, base_reg, offset, gmask, op)
+ FILE *file;
+ char *base_reg;
+ unsigned int offset;
+ unsigned int gmask;
+ char *op;
+{
+ int regno;
+
+ if (gmask == 0)
+ return;
+
+ for (regno = 0; regno <= 31; regno++)
+ {
+ if ((gmask & (1L << regno)) != 0)
+ {
+ fprintf (file, "\t%s %s,[%s,%d]\n",
+ op, reg_names[regno], base_reg, offset);
+ offset += UNITS_PER_WORD;
+ }
+ }
+}
+
+/* Set up the stack and frame pointer (if desired) for the function. */
+
+void
+arc_output_function_prologue (file, size)
+ FILE *file;
+ int size;
+{
+ char *sp_str = reg_names[STACK_POINTER_REGNUM];
+ char *fp_str = reg_names[FRAME_POINTER_REGNUM];
+ unsigned int gmask = current_frame_info.gmask;
+ enum arc_function_type fn_type = arc_compute_function_type (current_function_decl);
+
+ /* If this is an interrupt handler, set up our stack frame.
+ ??? Optimize later. */
+ if (ARC_INTERRUPT_P (fn_type))
+ {
+ fprintf (file, "\t%s interrupt handler\n",
+ ASM_COMMENT_START);
+ fprintf (file, "\tsub %s,%s,16\n", sp_str, sp_str);
+ }
+
+ /* This is only for the human reader. */
+ fprintf (file, "\t%s BEGIN PROLOGUE %s vars= %d, regs= %d, args= %d, extra= %d\n",
+ ASM_COMMENT_START, ASM_COMMENT_START,
+ current_frame_info.var_size,
+ current_frame_info.reg_size / 4,
+ current_frame_info.args_size,
+ current_frame_info.extra_size);
+
+ size = ARC_STACK_ALIGN (size);
+ size = (! current_frame_info.initialized
+ ? arc_compute_frame_size (size)
+ : current_frame_info.total_size);
+
+ /* These cases shouldn't happen. Catch them now. */
+ if (size == 0 && gmask)
+ abort ();
+
+ /* Allocate space for register arguments if this is a variadic function. */
+ if (current_frame_info.pretend_size != 0)
+ fprintf (file, "\tsub %s,%s,%d\n",
+ sp_str, sp_str, current_frame_info.pretend_size);
+
+ /* The home-grown ABI says link register is saved first. */
+ if (MUST_SAVE_RETURN_ADDR)
+ fprintf (file, "\tst %s,[%s,%d]\n",
+ reg_names[RETURN_ADDR_REGNUM], sp_str, UNITS_PER_WORD);
+
+ /* Set up the previous frame pointer next (if we need to). */
+ if (frame_pointer_needed)
+ {
+ fprintf (file, "\tst %s,[%s]\n", fp_str, sp_str);
+ fprintf (file, "\tmov %s,%s\n", fp_str, sp_str);
+ }
+
+ /* ??? We don't handle the case where the saved regs are more than 252
+ bytes away from sp. This can be handled by decrementing sp once, saving
+ the regs, and then decrementing it again. The epilogue doesn't have this
+ problem as the `ld' insn takes reg+limm values (though it would be more
+ efficient to avoid reg+limm). */
+
+ /* Allocate the stack frame. */
+ if (size - current_frame_info.pretend_size > 0)
+ fprintf (file, "\tsub %s,%s,%d\n",
+ sp_str, sp_str, size - current_frame_info.pretend_size);
+
+ /* Save any needed call-saved regs (and call-used if this is an
+ interrupt handler). */
+ arc_save_restore (file, sp_str, current_frame_info.reg_offset,
+ /* The zeroing of these two bits is unnecessary,
+ but leave this in for clarity. */
+ gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
+ "st");
+
+ fprintf (file, "\t%s END PROLOGUE\n", ASM_COMMENT_START);
+}
+
+/* Do any necessary cleanup after a function to restore stack, frame,
+ and regs. */
+
+void
+arc_output_function_epilogue (file, size)
+ FILE *file;
+ int size;
+{
+ rtx epilogue_delay = current_function_epilogue_delay_list;
+ int noepilogue = FALSE;
+ enum arc_function_type fn_type = arc_compute_function_type (current_function_decl);
+
+ /* This is only for the human reader. */
+ fprintf (file, "\t%s EPILOGUE\n", ASM_COMMENT_START);
+
+ size = ARC_STACK_ALIGN (size);
+ size = (!current_frame_info.initialized
+ ? arc_compute_frame_size (size)
+ : current_frame_info.total_size);
+
+ if (size == 0 && epilogue_delay == 0)
+ {
+ rtx insn = get_last_insn ();
+
+ /* If the last insn was a BARRIER, we don't have to write any code
+ because a jump (aka return) was put there. */
+ if (GET_CODE (insn) == NOTE)
+ insn = prev_nonnote_insn (insn);
+ if (insn && GET_CODE (insn) == BARRIER)
+ noepilogue = TRUE;
+ }
+
+ if (!noepilogue)
+ {
+ unsigned int pretend_size = current_frame_info.pretend_size;
+ unsigned int frame_size = size - pretend_size;
+ int restored, fp_restored_p;
+ int can_trust_sp_p = !current_function_calls_alloca;
+ char *sp_str = reg_names[STACK_POINTER_REGNUM];
+ char *fp_str = reg_names[FRAME_POINTER_REGNUM];
+
+ /* ??? There are lots of optimizations that can be done here.
+ EG: Use fp to restore regs if it's closer.
+ Maybe in time we'll do them all. For now, always restore regs from
+ sp, but don't restore sp if we don't have to. */
+
+ if (!can_trust_sp_p)
+ {
+ if (!frame_pointer_needed)
+ abort ();
+ fprintf (file,"\tsub %s,%s,%d\t\t%s sp not trusted here\n",
+ sp_str, fp_str, frame_size, ASM_COMMENT_START);
+ }
+
+ /* Restore any saved registers. */
+ arc_save_restore (file, sp_str, current_frame_info.reg_offset,
+ /* The zeroing of these two bits is unnecessary,
+ but leave this in for clarity. */
+ current_frame_info.gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
+ "ld");
+
+ if (MUST_SAVE_RETURN_ADDR)
+ fprintf (file, "\tld %s,[%s,%d]\n",
+ reg_names[RETURN_ADDR_REGNUM],
+ frame_pointer_needed ? fp_str : sp_str,
+ UNITS_PER_WORD + (frame_pointer_needed ? 0 : frame_size));
+
+ /* Keep track of how much of the stack pointer we've restored.
+ It makes the following a lot more readable. */
+ restored = 0;
+ fp_restored_p = 0;
+
+ /* We try to emit the epilogue delay slot insn right after the load
+ of the return address register so that it can execute with the
+ stack intact. Secondly, loads are delayed. */
+ /* ??? If stack intactness is important, always emit now. */
+ if (MUST_SAVE_RETURN_ADDR && epilogue_delay != NULL_RTX)
+ {
+ final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1);
+ epilogue_delay = NULL_RTX;
+ }
+
+ if (frame_pointer_needed)
+ {
+ /* Try to restore the frame pointer in the delay slot. We can't,
+ however, if any of these is true. */
+ if (epilogue_delay != NULL_RTX
+ || !SMALL_INT (frame_size)
+ || pretend_size
+ || ARC_INTERRUPT_P (fn_type))
+ {
+ /* Note that we restore fp and sp here! */
+ fprintf (file, "\tld.a %s,[%s,%d]\n", fp_str, sp_str, frame_size);
+ restored += frame_size;
+ fp_restored_p = 1;
+ }
+ }
+ else if (!SMALL_INT (size /* frame_size + pretend_size */)
+ || ARC_INTERRUPT_P (fn_type))
+ {
+ fprintf (file, "\tadd %s,%s,%d\n", sp_str, sp_str, frame_size);
+ restored += frame_size;
+ }
+
+ /* These must be done before the return insn because the delay slot
+ does the final stack restore. */
+ if (ARC_INTERRUPT_P (fn_type))
+ {
+ if (epilogue_delay)
+ {
+ final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1);
+ }
+ }
+
+ /* Emit the return instruction. */
+ {
+ static int regs[4] = {
+ 0, RETURN_ADDR_REGNUM, ILINK1_REGNUM, ILINK2_REGNUM
+ };
+ fprintf (file, "\tj.d %s\n", reg_names[regs[fn_type]]);
+ }
+
+ /* If the only register saved is the return address, we need a
+ nop, unless we have an instruction to put into it. Otherwise
+ we don't since reloading multiple registers doesn't reference
+ the register being loaded. */
+
+ if (ARC_INTERRUPT_P (fn_type))
+ fprintf (file, "\tadd %s,%s,16\n", sp_str, sp_str);
+ else if (epilogue_delay != NULL_RTX)
+ {
+ if (frame_pointer_needed && !fp_restored_p)
+ abort ();
+ if (restored < size)
+ abort ();
+ final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1);
+ }
+ else if (frame_pointer_needed && !fp_restored_p)
+ {
+ if (!SMALL_INT (frame_size))
+ abort ();
+ /* Note that we restore fp and sp here! */
+ fprintf (file, "\tld.a %s,[%s,%d]\n", fp_str, sp_str, frame_size);
+ }
+ else if (restored < size)
+ {
+ if (!SMALL_INT (size - restored))
+ abort ();
+ fprintf (file, "\tadd %s,%s,%d\n",
+ sp_str, sp_str, size - restored);
+ }
+ else
+ fprintf (file, "\tnop\n");
+ }
+
+ /* Reset state info for each function. */
+ current_frame_info = zero_frame_info;
+ arc_compute_function_type (NULL_TREE);
+}
+
+/* Define the number of delay slots needed for the function epilogue.
+
+ Interrupt handlers can't have any epilogue delay slots (it's always needed
+ for something else, I think). For normal functions, we have to worry about
+ using call-saved regs as they'll be restored before the delay slot insn.
+ Functions with non-empty frames already have enough choices for the epilogue
+ delay slot so for now we only consider functions with empty frames. */
+
+int
+arc_delay_slots_for_epilogue ()
+{
+ if (arc_compute_function_type (current_function_decl) != ARC_FUNCTION_NORMAL)
+ return 0;
+ if (!current_frame_info.initialized)
+ (void) arc_compute_frame_size (get_frame_size ());
+ if (current_frame_info.total_size == 0)
+ return 1;
+ return 0;
+}
+
+/* Return true if TRIAL is a valid insn for the epilogue delay slot.
+ Any single length instruction which doesn't reference the stack or frame
+ pointer or any call-saved register is OK. SLOT will always be 0. */
+
+int
+arc_eligible_for_epilogue_delay (trial, slot)
+ rtx trial;
+ int slot;
+{
+ if (slot != 0)
+ abort ();
+
+ if (get_attr_length (trial) == 1
+ /* If registers where saved, presumably there's more than enough
+ possibilities for the delay slot. The alternative is something
+ more complicated (of course, if we expanded the epilogue as rtl
+ this problem would go away). */
+ /* ??? Note that this will always be true since only functions with
+ empty frames have epilogue delay slots. See
+ arc_delay_slots_for_epilogue. */
+ && current_frame_info.gmask == 0
+ && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (trial))
+ && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (trial)))
+ return 1;
+ return 0;
+}
+
+/* PIC */
+
+/* Set up PIC-specific rtl. This should not cause any insns
+ to be emitted. */
+
+void
+arc_initialize_pic ()
+{
+ /* nothing to do */
+}
+
+/* Emit special PIC prologues and epilogues. */
+
+void
+arc_finalize_pic ()
+{
+ /* nothing to do */
+}
+
+/* Return true if OP is a shift operator. */
+
+int
+shift_operator (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ switch (GET_CODE (op))
+ {
+ case ASHIFTRT:
+ case LSHIFTRT:
+ case ASHIFT:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* Output the assembler code for doing a shift.
+ We go to a bit of trouble to generate efficient code as the ARC only has
+ single bit shifts. This is taken from the h8300 port. We only have one
+ mode of shifting and can't access individual bytes like the h8300 can, so
+ this is greatly simplified (at the expense of not generating hyper-
+ efficient code).
+
+ This function is not used if the variable shift insns are present. */
+
+/* ??? We assume the output operand is the same as operand 1.
+ This can be optimized (deleted) in the case of 1 bit shifts. */
+/* ??? We use the loop register here. We don't use it elsewhere (yet) and
+ using it here will give us a chance to play with it. */
+
+char *
+output_shift (operands)
+ rtx *operands;
+{
+ static int loopend_lab;
+ rtx shift = operands[3];
+ enum machine_mode mode = GET_MODE (shift);
+ enum rtx_code code = GET_CODE (shift);
+ char *shift_one;
+
+ if (mode != SImode)
+ abort ();
+
+ switch (code)
+ {
+ case ASHIFT: shift_one = "asl %0,%0"; break;
+ case ASHIFTRT: shift_one = "asr %0,%0"; break;
+ case LSHIFTRT: shift_one = "lsr %0,%0"; break;
+ default: abort ();
+ }
+
+ if (GET_CODE (operands[2]) != CONST_INT)
+ {
+ if (optimize)
+ output_asm_insn ("mov lp_count,%2", operands);
+ else
+ output_asm_insn ("mov %4,%2", operands);
+ goto shiftloop;
+ }
+ else
+ {
+ int n = INTVAL (operands[2]);
+
+ /* If the count is negative, make it 0. */
+ if (n < 0)
+ n = 0;
+ /* If the count is too big, truncate it.
+ ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
+ do the intuitive thing. */
+ else if (n > GET_MODE_BITSIZE (mode))
+ n = GET_MODE_BITSIZE (mode);
+
+ /* First see if we can do them inline. */
+ if (n <= 8)
+ {
+ while (--n >= 0)
+ output_asm_insn (shift_one, operands);
+ }
+ /* See if we can use a rotate/and. */
+ else if (n == BITS_PER_WORD - 1)
+ {
+ switch (code)
+ {
+ case ASHIFT :
+ output_asm_insn ("and %0,%0,1\n\tror %0,%0", operands);
+ break;
+ case ASHIFTRT :
+ /* The ARC doesn't have a rol insn. Use something else. */
+ output_asm_insn ("asl.f 0,%0\n\tsbc %0,0,0", operands);
+ break;
+ case LSHIFTRT :
+ /* The ARC doesn't have a rol insn. Use something else. */
+ output_asm_insn ("asl.f 0,%0\n\tadc %0,0,0", operands);
+ break;
+ }
+ }
+ /* Must loop. */
+ else
+ {
+ char buf[100];
+
+ if (optimize)
+ output_asm_insn ("mov lp_count,%c2", operands);
+ else
+ output_asm_insn ("mov %4,%c2", operands);
+ shiftloop:
+ if (optimize)
+ {
+ if (flag_pic)
+ sprintf ("lr %%4,[status]\n\tadd %%4,%%4,6\t%s single insn loop start",
+ ASM_COMMENT_START);
+ else
+ sprintf (buf, "mov %%4,%%%%st(1f)\t%s (single insn loop start) >> 2",
+ ASM_COMMENT_START);
+ output_asm_insn (buf, operands);
+ output_asm_insn ("sr %4,[lp_start]", operands);
+ output_asm_insn ("add %4,%4,1", operands);
+ output_asm_insn ("sr %4,[lp_end]", operands);
+ output_asm_insn ("nop\n\tnop", operands);
+ if (flag_pic)
+ asm_fprintf (asm_out_file, "\t%s single insn loop\n",
+ ASM_COMMENT_START);
+ else
+ asm_fprintf (asm_out_file, "1:\t%s single insn loop\n",
+ ASM_COMMENT_START);
+ output_asm_insn (shift_one, operands);
+ }
+ else
+ {
+ asm_fprintf (asm_out_file, "1:\t%s begin shift loop\n",
+ ASM_COMMENT_START);
+ output_asm_insn ("sub.f %4,%4,1", operands);
+ output_asm_insn ("nop", operands);
+ output_asm_insn ("bn.nd 2f", operands);
+ output_asm_insn (shift_one, operands);
+ output_asm_insn ("b.nd 1b", operands);
+ asm_fprintf (asm_out_file, "2:\t%s end shift loop\n",
+ ASM_COMMENT_START);
+ }
+ }
+ }
+
+ return "";
+}
+
+/* Nested function support. */
+
+/* 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. */
+
+void
+arc_initialize_trampoline (tramp, fnaddr, cxt)
+ rtx tramp, fnaddr, cxt;
+{
+}
+
+/* Set the cpu type and print out other fancy things,
+ at the top of the file. */
+
+void
+arc_asm_file_start (file)
+ FILE *file;
+{
+ fprintf (file, "\t.cpu %s\n", arc_cpu_string);
+}
+
+/* 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.
+ For `%' followed by punctuation, CODE is the punctuation and X is null. */
+
+void
+arc_print_operand (file, x, code)
+ FILE *file;
+ rtx x;
+ int code;
+{
+ switch (code)
+ {
+ case '#' :
+ /* Conditional branches. For now these are equivalent. */
+ case '*' :
+ /* Unconditional branches. Output the appropriate delay slot suffix. */
+ if (!final_sequence || XVECLEN (final_sequence, 0) == 1)
+ {
+ /* There's nothing in the delay slot. */
+ fputs (".nd", file);
+ }
+ else
+ {
+ rtx jump = XVECEXP (final_sequence, 0, 0);
+ rtx delay = XVECEXP (final_sequence, 0, 1);
+ if (INSN_ANNULLED_BRANCH_P (jump))
+ fputs (INSN_FROM_TARGET_P (delay) ? ".jd" : ".nd", file);
+ else
+ fputs (".d", file);
+ }
+ return;
+ case '?' : /* with leading "." */
+ case '!' : /* without leading "." */
+ /* This insn can be conditionally executed. See if the ccfsm machinery
+ says it should be conditionalized. */
+ if (arc_ccfsm_state == 3 || arc_ccfsm_state == 4)
+ {
+ /* Is this insn in a delay slot? */
+ if (final_sequence && XVECLEN (final_sequence, 0) == 2)
+ {
+ rtx insn = XVECEXP (final_sequence, 0, 1);
+
+ /* If the insn is annulled and is from the target path, we need
+ to inverse the condition test. */
+ if (INSN_ANNULLED_BRANCH_P (insn))
+ {
+ if (INSN_FROM_TARGET_P (insn))
+ fprintf (file, "%s%s",
+ code == '?' ? "." : "",
+ arc_condition_codes[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current_cc)]);
+ else
+ fprintf (file, "%s%s",
+ code == '?' ? "." : "",
+ arc_condition_codes[arc_ccfsm_current_cc]);
+ }
+ else
+ /* This insn is executed for either path, so don't
+ conditionalize it at all. */
+ ; /* nothing to do */
+ }
+ else
+ {
+ /* This insn isn't in a delay slot. */
+ fprintf (file, "%s%s",
+ code == '?' ? "." : "",
+ arc_condition_codes[arc_ccfsm_current_cc]);
+ }
+ }
+ return;
+ case '~' :
+ /* Output a nop if we're between a set of the condition codes,
+ and a conditional branch. */
+ if (last_insn_set_cc_p)
+ fputs ("nop\n\t", file);
+ return;
+ case 'd' :
+ fputs (arc_condition_codes[get_arc_condition_code (x)], file);
+ return;
+ case 'D' :
+ fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
+ (get_arc_condition_code (x))],
+ file);
+ return;
+ case 'R' :
+ /* Write second word of DImode or DFmode reference,
+ register or memory. */
+ if (GET_CODE (x) == REG)
+ fputs (reg_names[REGNO (x)+1], file);
+ else if (GET_CODE (x) == MEM)
+ {
+ fputc ('[', file);
+ /* Handle possible auto-increment. Since it is pre-increment and
+ we have already done it, we can just use an offset of four. */
+ /* ??? This is taken from rs6000.c I think. I don't think it is
+ currently necessary, but keep it around. */
+ if (GET_CODE (XEXP (x, 0)) == PRE_INC
+ || GET_CODE (XEXP (x, 0)) == PRE_DEC)
+ output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
+ else
+ output_address (plus_constant (XEXP (x, 0), 4));
+ fputc (']', file);
+ }
+ else
+ output_operand_lossage ("invalid operand to %R code");
+ return;
+ case 'S' :
+ if ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FLAG (x))
+ || GET_CODE (x) == LABEL_REF)
+ {
+ fprintf (file, "%%st(");
+ output_addr_const (file, x);
+ fprintf (file, ")");
+ return;
+ }
+ break;
+ case 'H' :
+ case 'L' :
+ if (GET_CODE (x) == REG)
+ {
+ /* L = least significant word, H = most significant word */
+ if ((TARGET_BIG_ENDIAN != 0) ^ (code == 'L'))
+ fputs (reg_names[REGNO (x)], file);
+ else
+ fputs (reg_names[REGNO (x)+1], file);
+ }
+ else if (GET_CODE (x) == CONST_INT
+ || GET_CODE (x) == CONST_DOUBLE)
+ {
+ rtx first, second;
+
+ split_double (x, &first, &second);
+ fprintf (file, "0x%08lx",
+ code == 'L' ? INTVAL (first) : INTVAL (second));
+ }
+ else
+ output_operand_lossage ("invalid operand to %H/%L code");
+ return;
+ case 'A' :
+ {
+ REAL_VALUE_TYPE d;
+ char str[30];
+
+ if (GET_CODE (x) != CONST_DOUBLE
+ || GET_MODE_CLASS (GET_MODE (x)) != MODE_FLOAT)
+ abort ();
+ REAL_VALUE_FROM_CONST_DOUBLE (d, x);
+ REAL_VALUE_TO_DECIMAL (d, "%.20e", str);
+ fprintf (file, "%s", str);
+ return;
+ }
+ case 'U' :
+ /* Output a load/store with update indicator if appropriate. */
+ if (GET_CODE (x) == MEM)
+ {
+ if (GET_CODE (XEXP (x, 0)) == PRE_INC
+ || GET_CODE (XEXP (x, 0)) == PRE_DEC)
+ fputs (".a", file);
+ }
+ else
+ output_operand_lossage ("invalid operand to %U code");
+ return;
+ case 'V' :
+ /* Output cache bypass indicator for a load/store insn. Volatile memory
+ refs are defined to use the cache bypass mechanism. */
+ if (GET_CODE (x) == MEM)
+ {
+ if (MEM_VOLATILE_P (x))
+ fputs (".di", file);
+ }
+ else
+ output_operand_lossage ("invalid operand to %V code");
+ return;
+ case 0 :
+ /* Do nothing special. */
+ break;
+ default :
+ /* Unknown flag. */
+ output_operand_lossage ("invalid operand output code");
+ }
+
+ switch (GET_CODE (x))
+ {
+ case REG :
+ fputs (reg_names[REGNO (x)], file);
+ break;
+ case MEM :
+ fputc ('[', file);
+ if (GET_CODE (XEXP (x, 0)) == PRE_INC)
+ output_address (plus_constant (XEXP (XEXP (x, 0), 0),
+ GET_MODE_SIZE (GET_MODE (x))));
+ else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
+ output_address (plus_constant (XEXP (XEXP (x, 0), 0),
+ - GET_MODE_SIZE (GET_MODE (x))));
+ else
+ output_address (XEXP (x, 0));
+ fputc (']', file);
+ break;
+ case CONST_DOUBLE :
+ /* We handle SFmode constants here as output_addr_const doesn't. */
+ if (GET_MODE (x) == SFmode)
+ {
+ REAL_VALUE_TYPE d;
+ long l;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (d, x);
+ REAL_VALUE_TO_TARGET_SINGLE (d, l);
+ fprintf (file, "0x%08lx", l);
+ break;
+ }
+ /* Fall through. Let output_addr_const deal with it. */
+ default :
+ output_addr_const (file, x);
+ break;
+ }
+}
+
+/* Print a memory address as an operand to reference that memory location. */
+
+void
+arc_print_operand_address (file, addr)
+ FILE *file;
+ rtx addr;
+{
+ register rtx base, index = 0;
+ int offset = 0;
+
+ switch (GET_CODE (addr))
+ {
+ case REG :
+ fputs (reg_names[REGNO (addr)], file);
+ break;
+ case SYMBOL_REF :
+ if (/*???*/ 0 && SYMBOL_REF_FLAG (addr))
+ {
+ fprintf (file, "%%st(");
+ output_addr_const (file, addr);
+ fprintf (file, ")");
+ }
+ else
+ output_addr_const (file, addr);
+ break;
+ case PLUS :
+ if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
+ offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);
+ else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);
+ else
+ base = XEXP (addr, 0), index = XEXP (addr, 1);
+ if (GET_CODE (base) != REG)
+ abort ();
+ fputs (reg_names[REGNO (base)], file);
+ if (index == 0)
+ {
+ if (offset != 0)
+ fprintf (file, ",%d", offset);
+ }
+ else if (GET_CODE (index) == REG)
+ fprintf (file, ",%s", reg_names[REGNO (index)]);
+ else if (GET_CODE (index) == SYMBOL_REF)
+ fputc (',', file), output_addr_const (file, index);
+ else
+ abort ();
+ break;
+ case PRE_INC :
+ case PRE_DEC :
+ /* We shouldn't get here as we've lost the mode of the memory object
+ (which says how much to inc/dec by. */
+ abort ();
+ break;
+ default :
+ output_addr_const (file, addr);
+ break;
+ }
+}
+
+/* Update compare/branch separation marker. */
+
+static void
+record_cc_ref (insn)
+ rtx insn;
+{
+ last_insn_set_cc_p = current_insn_set_cc_p;
+
+ switch (get_attr_cond (insn))
+ {
+ case COND_SET :
+ case COND_SET_ZN :
+ case COND_SET_ZNC :
+ if (get_attr_length (insn) == 1)
+ current_insn_set_cc_p = 1;
+ else
+ current_insn_set_cc_p = 0;
+ break;
+ default :
+ current_insn_set_cc_p = 0;
+ break;
+ }
+}
+
+/* Conditional execution support.
+
+ This is based on the ARM port but for now is much simpler.
+
+ A finite state machine takes care of noticing whether or not instructions
+ can be conditionally executed, and thus decrease execution time and code
+ size by deleting branch instructions. The fsm is controlled by
+ final_prescan_insn, and controls the actions of PRINT_OPERAND. The patterns
+ in the .md file for the branch insns also have a hand in this. */
+
+/* The state of the fsm controlling condition codes are:
+ 0: normal, do nothing special
+ 1: don't output this insn
+ 2: don't output this insn
+ 3: make insns conditional
+ 4: make insns conditional
+
+ State transitions (state->state by whom, under what condition):
+ 0 -> 1 final_prescan_insn, if insn is conditional branch
+ 0 -> 2 final_prescan_insn, if the `target' is an unconditional branch
+ 1 -> 3 branch patterns, after having not output the conditional branch
+ 2 -> 4 branch patterns, after having not output the conditional branch
+ 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
+ (the target label has CODE_LABEL_NUMBER equal to
+ arc_ccfsm_target_label).
+ 4 -> 0 final_prescan_insn, if `target' unconditional branch is reached
+
+ If the jump clobbers the conditions then we use states 2 and 4.
+
+ A similar thing can be done with conditional return insns.
+
+ We also handle separating branches from sets of the condition code.
+ This is done here because knowledge of the ccfsm state is required,
+ we may not be outputting the branch. */
+
+void
+arc_final_prescan_insn (insn, opvec, noperands)
+ rtx insn;
+ rtx *opvec;
+ int noperands;
+{
+ /* BODY will hold the body of INSN. */
+ register rtx body = PATTERN (insn);
+
+ /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
+ an if/then/else), and things need to be reversed. */
+ int reverse = 0;
+
+ /* If we start with a return insn, we only succeed if we find another one. */
+ int seeking_return = 0;
+
+ /* START_INSN will hold the insn from where we start looking. This is the
+ first insn after the following code_label if REVERSE is true. */
+ rtx start_insn = insn;
+
+ /* Update compare/branch separation marker. */
+ record_cc_ref (insn);
+
+ /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
+ We can't do this in macro FINAL_PRESCAN_INSN because it's called from
+ final_scan_insn which has `optimize' as a local. */
+ if (optimize < 2 || TARGET_NO_COND_EXEC)
+ return;
+
+ /* If in state 4, check if the target branch is reached, in order to
+ change back to state 0. */
+ if (arc_ccfsm_state == 4)
+ {
+ if (insn == arc_ccfsm_target_insn)
+ {
+ arc_ccfsm_target_insn = NULL;
+ arc_ccfsm_state = 0;
+ }
+ return;
+ }
+
+ /* If in state 3, it is possible to repeat the trick, if this insn is an
+ unconditional branch to a label, and immediately following this branch
+ is the previous target label which is only used once, and the label this
+ branch jumps to is not too far off. Or in other words "we've done the
+ `then' part, see if we can do the `else' part." */
+ if (arc_ccfsm_state == 3)
+ {
+ if (simplejump_p (insn))
+ {
+ start_insn = next_nonnote_insn (start_insn);
+ if (GET_CODE (start_insn) == BARRIER)
+ {
+ /* ??? Isn't this always a barrier? */
+ start_insn = next_nonnote_insn (start_insn);
+ }
+ if (GET_CODE (start_insn) == CODE_LABEL
+ && CODE_LABEL_NUMBER (start_insn) == arc_ccfsm_target_label
+ && LABEL_NUSES (start_insn) == 1)
+ reverse = TRUE;
+ else
+ return;
+ }
+ else if (GET_CODE (body) == RETURN)
+ {
+ start_insn = next_nonnote_insn (start_insn);
+ if (GET_CODE (start_insn) == BARRIER)
+ start_insn = next_nonnote_insn (start_insn);
+ if (GET_CODE (start_insn) == CODE_LABEL
+ && CODE_LABEL_NUMBER (start_insn) == arc_ccfsm_target_label
+ && LABEL_NUSES (start_insn) == 1)
+ {
+ reverse = TRUE;
+ seeking_return = 1;
+ }
+ else
+ return;
+ }
+ else
+ return;
+ }
+
+ if (GET_CODE (insn) != JUMP_INSN)
+ return;
+
+ /* This jump might be paralleled with a clobber of the condition codes,
+ the jump should always come first. */
+ if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
+ body = XVECEXP (body, 0, 0);
+
+ if (reverse
+ || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
+ && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
+ {
+ int insns_skipped = 0, fail = FALSE, succeed = FALSE;
+ /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
+ int then_not_else = TRUE;
+ /* Nonzero if next insn must be the target label. */
+ int next_must_be_target_label_p;
+ rtx this_insn = start_insn, label = 0;
+
+ /* Register the insn jumped to. */
+ if (reverse)
+ {
+ if (!seeking_return)
+ label = XEXP (SET_SRC (body), 0);
+ }
+ else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
+ label = XEXP (XEXP (SET_SRC (body), 1), 0);
+ else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
+ {
+ label = XEXP (XEXP (SET_SRC (body), 2), 0);
+ then_not_else = FALSE;
+ }
+ else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)
+ seeking_return = 1;
+ else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)
+ {
+ seeking_return = 1;
+ then_not_else = FALSE;
+ }
+ else
+ abort ();
+
+ /* See how many insns this branch skips, and what kind of insns. If all
+ insns are okay, and the label or unconditional branch to the same
+ label is not too far away, succeed. */
+ for (insns_skipped = 0, next_must_be_target_label_p = FALSE;
+ !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED;
+ insns_skipped++)
+ {
+ rtx scanbody;
+
+ this_insn = next_nonnote_insn (this_insn);
+ if (!this_insn)
+ break;
+
+ if (next_must_be_target_label_p)
+ {
+ if (GET_CODE (this_insn) == BARRIER)
+ continue;
+ if (GET_CODE (this_insn) == CODE_LABEL
+ && this_insn == label)
+ {
+ arc_ccfsm_state = 1;
+ succeed = TRUE;
+ }
+ else
+ fail = TRUE;
+ break;
+ }
+
+ scanbody = PATTERN (this_insn);
+
+ switch (GET_CODE (this_insn))
+ {
+ case CODE_LABEL:
+ /* Succeed if it is the target label, otherwise fail since
+ control falls in from somewhere else. */
+ if (this_insn == label)
+ {
+ arc_ccfsm_state = 1;
+ succeed = TRUE;
+ }
+ else
+ fail = TRUE;
+ break;
+
+ case BARRIER:
+ /* Succeed if the following insn is the target label.
+ Otherwise fail.
+ If return insns are used then the last insn in a function
+ will be a barrier. */
+ next_must_be_target_label_p = TRUE;
+ break;
+
+ case CALL_INSN:
+ /* Can handle a call insn if there are no insns after it.
+ IE: The next "insn" is the target label. We don't have to
+ worry about delay slots as such insns are SEQUENCE's inside
+ INSN's. ??? It is possible to handle such insns though. */
+ if (get_attr_cond (this_insn) == COND_CANUSE)
+ next_must_be_target_label_p = TRUE;
+ else
+ fail = TRUE;
+ break;
+
+ case JUMP_INSN:
+ /* If this is an unconditional branch to the same label, succeed.
+ If it is to another label, do nothing. If it is conditional,
+ fail. */
+ /* ??? Probably, the test for the SET and the PC are unnecessary. */
+
+ if (GET_CODE (scanbody) == SET
+ && GET_CODE (SET_DEST (scanbody)) == PC)
+ {
+ if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
+ && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
+ {
+ arc_ccfsm_state = 2;
+ succeed = TRUE;
+ }
+ else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
+ fail = TRUE;
+ }
+ else if (GET_CODE (scanbody) == RETURN
+ && seeking_return)
+ {
+ arc_ccfsm_state = 2;
+ succeed = TRUE;
+ }
+ else if (GET_CODE (scanbody) == PARALLEL)
+ {
+ if (get_attr_cond (this_insn) != COND_CANUSE)
+ fail = TRUE;
+ }
+ break;
+
+ case INSN:
+ /* We can only do this with insns that can use the condition
+ codes (and don't set them). */
+ if (GET_CODE (scanbody) == SET
+ || GET_CODE (scanbody) == PARALLEL)
+ {
+ if (get_attr_cond (this_insn) != COND_CANUSE)
+ fail = TRUE;
+ }
+ /* We can't handle other insns like sequences. */
+ else
+ fail = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (succeed)
+ {
+ if ((!seeking_return) && (arc_ccfsm_state == 1 || reverse))
+ arc_ccfsm_target_label = CODE_LABEL_NUMBER (label);
+ else if (seeking_return || arc_ccfsm_state == 2)
+ {
+ while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
+ {
+ this_insn = next_nonnote_insn (this_insn);
+ if (this_insn && (GET_CODE (this_insn) == BARRIER
+ || GET_CODE (this_insn) == CODE_LABEL))
+ abort ();
+ }
+ if (!this_insn)
+ {
+ /* Oh dear! we ran off the end, give up. */
+ insn_extract (insn);
+ arc_ccfsm_state = 0;
+ arc_ccfsm_target_insn = NULL;
+ return;
+ }
+ arc_ccfsm_target_insn = this_insn;
+ }
+ else
+ abort ();
+
+ /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
+ what it was. */
+ if (!reverse)
+ arc_ccfsm_current_cc = get_arc_condition_code (XEXP (SET_SRC (body),
+ 0));
+
+ if (reverse || then_not_else)
+ arc_ccfsm_current_cc = ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current_cc);
+ }
+
+ /* Restore recog_operand. Getting the attributes of other insns can
+ destroy this array, but final.c assumes that it remains intact
+ across this call; since the insn has been recognized already we
+ call insn_extract direct. */
+ insn_extract (insn);
+ }
+}
+
+/* Record that we are currently outputting label NUM with prefix PREFIX.
+ It it's the label we're looking for, reset the ccfsm machinery.
+
+ Called from ASM_OUTPUT_INTERNAL_LABEL. */
+
+void
+arc_ccfsm_at_label (prefix, num)
+ char *prefix;
+ int num;
+{
+ if (arc_ccfsm_state == 3 && arc_ccfsm_target_label == num
+ && !strcmp (prefix, "L"))
+ {
+ arc_ccfsm_state = 0;
+ arc_ccfsm_target_insn = NULL_RTX;
+ }
+}
+
+/* See if the current insn, which is a conditional branch, is to be
+ deleted. */
+
+int
+arc_ccfsm_branch_deleted_p ()
+{
+ if (arc_ccfsm_state == 1 || arc_ccfsm_state == 2)
+ return 1;
+ return 0;
+}
+
+/* Record a branch isn't output because subsequent insns can be
+ conditionalized. */
+
+void
+arc_ccfsm_record_branch_deleted ()
+{
+ /* Indicate we're conditionalizing insns now. */
+ arc_ccfsm_state += 2;
+
+ /* If the next insn is a subroutine call, we still need a nop between the
+ cc setter and user. We need to undo the effect of calling record_cc_ref
+ for the just deleted branch. */
+ current_insn_set_cc_p = last_insn_set_cc_p;
+}
diff --git a/gnu/usr.bin/gcc/config/arc/arc.h b/gnu/usr.bin/gcc/config/arc/arc.h
new file mode 100644
index 00000000000..4257efaee3b
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arc/arc.h
@@ -0,0 +1,1643 @@
+/* Definitions of target machine for GNU compiler, Argonaut ARC cpu.
+ Copyright (C) 1994, 1995, 1997 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 an old port, and is undoubtedly suffering from bit rot. */
+
+/* Things to do:
+
+ - PREDICATE_CODES
+ - incscc, decscc?
+ - print active compiler options in assembler output
+*/
+
+/* ??? Create elf.h and have svr4.h include it. */
+#include "svr4.h"
+
+#undef ASM_SPEC
+#undef LINK_SPEC
+#undef STARTFILE_SPEC
+#undef ENDFILE_SPEC
+#undef SIZE_TYPE
+#undef PTRDIFF_TYPE
+#undef WCHAR_TYPE
+#undef WCHAR_TYPE_SIZE
+
+/* Print subsidiary information on the compiler version in use. */
+#define TARGET_VERSION fprintf (stderr, " (arc)")
+
+/* Names to predefine in the preprocessor for this target machine. */
+#define CPP_PREDEFINES "-Acpu(arc) -Amachine(arc) -D__arc__"
+
+/* Additional flags for the preprocessor. */
+#define CPP_SPEC "\
+%{!mcpu=*:-D__base__} %{mcpu=base:-D__base__} \
+%{EB:-D__big_endian__} \
+"
+
+/* Pass -mmangle-cpu if we get -mcpu=*.
+ Doing it this way lets one have it on as default with -mcpu=*,
+ but also lets one turn it off with -mno-mangle-cpu. */
+#define CC1_SPEC "\
+%{mcpu=*:-mmangle-cpu} \
+%{EB:%{EL:%emay not use both -EB and -EL}} \
+%{EB:-mbig-endian} %{EL:-mlittle-endian} \
+"
+
+#define ASM_SPEC "%{v} %{EB} %{EL}"
+
+#define LINK_SPEC "%{v} %{EB} %{EL}"
+
+#define STARTFILE_SPEC "%{!shared:crt0.o%s} crtinit.o%s"
+
+#define ENDFILE_SPEC "crtfini.o%s"
+
+/* Run-time compilation parameters selecting different hardware subsets. */
+
+extern int target_flags;
+
+/* Mangle all user symbols for the specified cpu.
+ ARC's can be shipped in which a collection of cpus are coupled together.
+ Each CPU may be different in some way, and thus we may need to distinguish
+ code compiled for one to ensure it isn't linked with code compiled for
+ another. */
+#define TARGET_MASK_MANGLE_CPU 1
+#define TARGET_MANGLE_CPU (target_flags & TARGET_MASK_MANGLE_CPU)
+
+#if 0
+/* Mangle libgcc symbols by adding a suffix for the specified cpu. */
+#define TARGET_MASK_MANGLE_CPU_LIBGCC 2
+#define TARGET_MANGLE_CPU_LIBGCC (target_flags & TARGET_MASK_MANGLE_CPU_LIBGCC)
+#endif
+
+/* Align loops to 32 byte boundaries (cache line size). */
+#define TARGET_MASK_ALIGN_LOOPS 4
+#define TARGET_ALIGN_LOOPS (target_flags & TARGET_MASK_ALIGN_LOOPS)
+
+/* Big Endian. */
+#define TARGET_MASK_BIG_ENDIAN 8
+#define TARGET_BIG_ENDIAN (target_flags & TARGET_MASK_BIG_ENDIAN)
+
+/* Turn off conditional execution optimization,
+ so we can see how well it does, or in case it's buggy. */
+#define TARGET_MASK_NO_COND_EXEC 0x10
+#define TARGET_NO_COND_EXEC (target_flags & TARGET_MASK_NO_COND_EXEC)
+
+/* Macro to define tables used to set the flags.
+ This is a list in braces of pairs in braces,
+ each pair being { "NAME", VALUE }
+ where VALUE is the bits to set or minus the bits to clear.
+ An empty string NAME is used to identify the default VALUE. */
+
+#define TARGET_SWITCHES \
+{ \
+ { "mangle-cpu", TARGET_MASK_MANGLE_CPU }, \
+ { "no-mangle-cpu", -TARGET_MASK_MANGLE_CPU }, \
+/* { "mangle-cpu-libgcc", TARGET_MASK_MANGLE_CPU_LIBGCC }, */ \
+/* { "no-mangle-cpu-libgcc", -TARGET_MASK_MANGLE_CPU_LIBGCC }, */ \
+ { "align-loops", TARGET_MASK_ALIGN_LOOPS }, \
+ { "no-align-loops", -TARGET_MASK_ALIGN_LOOPS }, \
+ { "big-endian", TARGET_MASK_BIG_ENDIAN }, \
+ { "little-endian", -TARGET_MASK_BIG_ENDIAN }, \
+ { "no-cond-exec", TARGET_MASK_NO_COND_EXEC }, \
+ SUBTARGET_SWITCHES \
+ { "", TARGET_DEFAULT } \
+}
+
+#define TARGET_DEFAULT (0)
+
+#define SUBTARGET_SWITCHES
+
+/* Instruction set characteristics.
+ These are internal macros, set by the appropriate -mcpu= option. */
+
+/* Non-zero means the cpu has a barrel shifter. */
+#define TARGET_SHIFTER 0
+
+/* 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.
+
+ Here is an example which defines `-mshort-data-NUMBER'. If the
+ given option is `-mshort-data-512', the variable `m88k_short_data'
+ will be set to the string `"512"'.
+
+ extern char *m88k_short_data;
+ #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */
+
+extern char *arc_cpu_string;
+extern char *arc_text_string,*arc_data_string,*arc_rodata_string;
+
+#define TARGET_OPTIONS \
+{ \
+ { "cpu=", &arc_cpu_string }, \
+ { "text=", &arc_text_string }, \
+ { "data=", &arc_data_string }, \
+ { "rodata=", &arc_rodata_string }, \
+}
+
+/* Which cpu we're compiling for. */
+extern int arc_cpu_type;
+
+/* Check if CPU is an extension and set `arc_cpu_type' and `arc_mangle_cpu'
+ appropriately. The result should be non-zero if the cpu is recognized,
+ otherwise zero. This is intended to be redefined in a cover file.
+ This is used by arc_init. */
+#define ARC_EXTENSION_CPU(cpu) 0
+
+/* 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. */
+
+extern void arc_init ();
+
+#define OVERRIDE_OPTIONS \
+do { \
+ /* These need to be done at start up. It's convenient to do them here. */ \
+ arc_init (); \
+} while (0)
+
+/* Target machine storage layout. */
+
+/* Define to use software floating point emulator for REAL_ARITHMETIC and
+ decimal <-> binary conversion. */
+#define REAL_ARITHMETIC
+
+/* Define this if most significant bit is lowest numbered
+ in instructions that operate on numbered bit-fields. */
+#define BITS_BIG_ENDIAN 1
+
+/* Define this if most significant byte of a word is the lowest numbered. */
+#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN)
+
+/* Define this if most significant word of a multiword number is the lowest
+ numbered. */
+#define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN)
+
+/* Define this to set the endianness to use in libgcc2.c, which can
+ not depend on target_flags. */
+#ifdef __big_endian__
+#define LIBGCC2_WORDS_BIG_ENDIAN 1
+#else
+#define LIBGCC2_WORDS_BIG_ENDIAN 0
+#endif
+
+/* 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 68000, 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
+
+/* 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 macro if the promotion described by `PROMOTE_MODE'
+ should also be done for outgoing function arguments. */
+#define PROMOTE_FUNCTION_ARGS
+
+/* Likewise, if the function return value is promoted. */
+#define PROMOTE_FUNCTION_RETURN
+
+/* 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 64
+
+/* ALIGN FRAMES on word boundaries */
+#define ARC_STACK_ALIGN(LOC) (((LOC)+7) & ~7)
+
+/* Allocation boundary (in *bits*) for the code of a function. */
+#define FUNCTION_BOUNDARY 32
+
+/* Alignment of field after `int : 0' in a structure. */
+#define EMPTY_FIELD_BOUNDARY 32
+
+/* Every structure's size must be a multiple of this. */
+#define STRUCTURE_SIZE_BOUNDARY 8
+
+/* A bitfield declared as `int' forces `int' alignment for the struct. */
+#define PCC_BITFIELD_TYPE_MATTERS 1
+
+/* No data type wants to be aligned rounder than this. */
+/* This is bigger than currently necessary for the ARC. If 8 byte floats are
+ ever added it's not clear whether they'll need such alignment or not. For
+ now we assume they will. We can always relax it if necessary but the
+ reverse isn't true. */
+#define BIGGEST_ALIGNMENT 64
+
+/* The best alignment to use in cases where we have a choice. */
+#define FASTEST_ALIGNMENT 32
+
+/* Make strings word-aligned so strcpy from constants will be faster. */
+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
+ ((TREE_CODE (EXP) == STRING_CST \
+ && (ALIGN) < FASTEST_ALIGNMENT) \
+ ? FASTEST_ALIGNMENT : (ALIGN))
+
+/* Make arrays of chars word-aligned for the same reasons. */
+#define DATA_ALIGNMENT(TYPE, ALIGN) \
+ (TREE_CODE (TYPE) == ARRAY_TYPE \
+ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
+ && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
+
+/* Set this nonzero if move instructions will actually fail to work
+ when given unaligned data. */
+/* On the ARC the lower address bits are masked to 0 as necessary. The chip
+ won't croak when given an unaligned address, but the insn will still fail
+ to produce the correct result. */
+#define STRICT_ALIGNMENT 1
+
+/* Layout of source language data types. */
+
+#define SHORT_TYPE_SIZE 16
+#define INT_TYPE_SIZE 32
+#define LONG_TYPE_SIZE 32
+#define LONG_LONG_TYPE_SIZE 64
+#define FLOAT_TYPE_SIZE 32
+#define DOUBLE_TYPE_SIZE 64
+#define LONG_DOUBLE_TYPE_SIZE 64
+
+/* Define this as 1 if `char' should by default be signed; else as 0. */
+#define DEFAULT_SIGNED_CHAR 1
+
+#define SIZE_TYPE "long unsigned int"
+#define PTRDIFF_TYPE "long int"
+#define WCHAR_TYPE "short unsigned int"
+#define WCHAR_TYPE_SIZE 16
+
+/* 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
+
+/* Standard register usage. */
+
+/* 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. */
+/* Registers 61, 62, and 63 are not really registers and we needn't treat
+ them as such. We still need a register for the condition code. */
+#define FIRST_PSEUDO_REGISTER 62
+
+/* 1 for registers that have pervasive standard uses
+ and are not available for the register allocator.
+
+ 0-28 - general purpose registers
+ 29 - ilink1 (interrupt link register)
+ 30 - ilink2 (interrupt link register)
+ 31 - blink (branch link register)
+ 32-59 - reserved for extensions
+ 60 - LP_COUNT
+ 61 - condition code
+
+ For doc purposes:
+ 61 - short immediate data indicator (setting flags)
+ 62 - long immediate data indicator
+ 63 - short immediate data indicator (not setting flags).
+
+ The general purpose registers are further broken down into:
+ 0-7 - arguments/results
+ 8-15 - call used
+ 16-23 - call saved
+ 24 - call used, static chain pointer
+ 25 - call used, gptmp
+ 26 - global pointer
+ 27 - frame pointer
+ 28 - stack pointer
+
+ By default, the extension registers are not available. */
+
+#define FIXED_REGISTERS \
+{ 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 1, 1, 1, 1, 0, \
+ \
+ 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 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 \
+{ 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 1, 1, 1, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ 1, 1, 1, 1, 1, 1, 1, 1, \
+ \
+ 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 1 }
+
+/* If defined, an initializer for a vector of integers, containing the
+ numbers of hard registers in the order in which GNU CC should
+ prefer to use them (from most preferred to least). */
+#define REG_ALLOC_ORDER \
+{ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, \
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 31, \
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, \
+ 27, 28, 29, 30 }
+
+/* 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. */
+#define HARD_REGNO_NREGS(REGNO, MODE) \
+((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. */
+extern unsigned int arc_hard_regno_mode_ok[];
+extern unsigned int arc_mode_class[];
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+((arc_hard_regno_mode_ok[REGNO] & arc_mode_class[MODE]) != 0)
+
+/* A C expression that is nonzero if it is desirable to choose
+ register allocation so as to avoid move instructions between a
+ value of mode MODE1 and a value of mode MODE2.
+
+ If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R,
+ MODE2)' are ever different for any R, then `MODES_TIEABLE_P (MODE1,
+ MODE2)' must be zero. */
+
+/* Tie QI/HI/SI modes together. */
+#define MODES_TIEABLE_P(MODE1, MODE2) \
+(GET_MODE_CLASS (MODE1) == MODE_INT \
+ && GET_MODE_CLASS (MODE2) == MODE_INT \
+ && GET_MODE_SIZE (MODE1) <= UNITS_PER_WORD \
+ && GET_MODE_SIZE (MODE2) <= UNITS_PER_WORD)
+
+/* Register classes and constants. */
+
+/* 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 is important that any condition codes have class NO_REGS.
+ See `register_operand'. */
+
+enum reg_class {
+ NO_REGS, LPCOUNT_REG, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
+};
+
+#define N_REG_CLASSES (int) LIM_REG_CLASSES
+
+/* Give names of register classes as strings for dump file. */
+#define REG_CLASS_NAMES \
+{ "NO_REGS", "LPCOUNT_REG", "GENERAL_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, 0}, {0, 0x10000000}, {0xffffffff, 0xfffffff}, \
+ {0xffffffff, 0x1fffffff} }
+
+/* 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. */
+extern enum reg_class arc_regno_reg_class[];
+#define REGNO_REG_CLASS(REGNO) \
+(arc_regno_reg_class[REGNO])
+
+/* The class value for index registers, and the one for base regs. */
+#define INDEX_REG_CLASS GENERAL_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) == 'l' ? LPCOUNT_REG /* ??? needed? */ \
+ : NO_REGS)
+
+/* 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_BASE_P(REGNO) \
+((REGNO) < 29 || (unsigned) reg_renumber[REGNO] < 29)
+#define REGNO_OK_FOR_INDEX_P(REGNO) \
+((REGNO) < 29 || (unsigned) reg_renumber[REGNO] < 29)
+
+/* 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. */
+#define PREFERRED_RELOAD_CLASS(X,CLASS) \
+(CLASS)
+
+/* Return the maximum number of consecutive registers
+ needed to represent mode MODE in a register of class CLASS. */
+#define CLASS_MAX_NREGS(CLASS, MODE) \
+((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* The letters I, J, K, L, M, N, O, P 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 used for short immediates (always signed).
+ 'J' is used for long immediates.
+ 'K' is used for any constant up to 64 bits (for 64x32 situations?). */
+
+/* local to this file */
+#define SMALL_INT(X) ((unsigned) ((X) + 0x100) < 0x200)
+/* local to this file */
+#define LARGE_INT(X) \
+((X) >= (-(HOST_WIDE_INT) 0x7fffffff - 1) \
+ && (X) <= (unsigned HOST_WIDE_INT) 0xffffffff)
+
+#define CONST_OK_FOR_LETTER_P(VALUE, C) \
+((C) == 'I' ? SMALL_INT (VALUE) \
+ : (C) == 'J' ? LARGE_INT (VALUE) \
+ : (C) == 'K' ? 1 \
+ : 0)
+
+/* Similar, but for floating constants, and defining letters G and H.
+ Here VALUE is the CONST_DOUBLE rtx itself. */
+/* 'G' is used for integer values for the multiplication insns where the
+ operands are extended from 4 bytes to 8 bytes.
+ 'H' is used when any 64 bit constant is allowed. */
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
+((C) == 'G' ? arc_double_limm_p (VALUE) \
+ : (C) == 'H' ? 1 \
+ : 0)
+
+/* A C expression that defines the optional machine-dependent constraint
+ letters that can be used to segregate specific types of operands,
+ usually memory references, for the target machine. It should return 1 if
+ VALUE corresponds to the operand type represented by the constraint letter
+ C. If C is not defined as an extra constraint, the value returned should
+ be 0 regardless of VALUE. */
+/* ??? This currently isn't used. Waiting for PIC. */
+#if 0
+#define EXTRA_CONSTRAINT(VALUE, C) \
+((C) == 'R' ? (SYMBOL_REF_FLAG (VALUE) || GET_CODE (VALUE) == LABEL_REF) \
+ : 0)
+#endif
+
+/* Stack layout and stack pointer usage. */
+
+/* Define this macro if pushing a word onto the stack moves the stack
+ pointer to 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
+
+/* Offset from the stack pointer register to the first location at which
+ outgoing arguments are placed. */
+#define STACK_POINTER_OFFSET FIRST_PARM_OFFSET (0)
+
+/* Offset of first parameter from the argument pointer register value. */
+/* 4 bytes for each of previous fp, return address, and previous gp.
+ 4 byte reserved area for future considerations. */
+#define FIRST_PARM_OFFSET(FNDECL) 16
+
+/* A C expression whose value is RTL representing the address in a
+ stack frame where the pointer to the caller's frame is stored.
+ Assume that FRAMEADDR is an RTL expression for the address of the
+ stack frame itself.
+
+ If you don't define this macro, the default is to return the value
+ of FRAMEADDR--that is, the stack frame address is also the address
+ of the stack word that points to the previous frame. */
+/* ??? unfinished */
+/*define DYNAMIC_CHAIN_ADDRESS (FRAMEADDR)*/
+
+/* A C expression whose value is RTL representing the value of the
+ return address for the frame COUNT steps up from the current frame.
+ FRAMEADDR is the frame pointer of the COUNT frame, or the frame
+ pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME'
+ is defined. */
+/* The current return address is in r31. The return address of anything
+ farther back is at [%fp,4]. */
+#if 0 /* The default value should work. */
+#define RETURN_ADDR_RTX(COUNT, FRAME) \
+(((COUNT) == -1) \
+ ? gen_rtx (REG, Pmode, 31) \
+ : copy_to_reg (gen_rtx (MEM, Pmode, \
+ memory_address (Pmode, plus_constant ((FRAME), UNITS_PER_WORD)))))
+#endif
+
+/* Register to use for pushing function arguments. */
+#define STACK_POINTER_REGNUM 28
+
+/* Base register for access to local variables of the function. */
+#define FRAME_POINTER_REGNUM 27
+
+/* Base register for access to arguments of the function. */
+#define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
+
+/* Register in which static-chain is passed to a function. This must
+ not be a register used by the prologue. */
+#define STATIC_CHAIN_REGNUM 24
+
+/* A C expression which is nonzero if a function must have and use a
+ frame pointer. This expression is evaluated in the reload pass.
+ If its value is nonzero the function will have a frame pointer. */
+#define FRAME_POINTER_REQUIRED \
+(current_function_calls_alloca)
+
+/* C statement to store the difference between the frame pointer
+ and the stack pointer values immediately after the function prologue. */
+#define INITIAL_FRAME_POINTER_OFFSET(VAR) \
+((VAR) = arc_compute_frame_size (get_frame_size ()))
+
+/* Function argument passing. */
+
+/* When a prototype says `char' or `short', really pass an `int'. */
+#define PROMOTE_PROTOTYPES
+
+/* If defined, the maximum amount of space required for outgoing
+ arguments will be computed and placed into the variable
+ `current_function_outgoing_args_size'. No space will be pushed
+ onto the stack for each call; instead, the function prologue should
+ increase the stack frame size by this amount. */
+#define ACCUMULATE_OUTGOING_ARGS
+
+/* 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. */
+#define RETURN_POPS_ARGS(DECL, FUNTYPE, SIZE) 0
+
+/* 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. */
+#define CUMULATIVE_ARGS int
+
+/* 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,INDIRECT) \
+((CUM) = 0)
+
+/* The number of registers used for parameter passing. Local to this file. */
+#define MAX_ARC_PARM_REGS 8
+
+/* 1 if N is a possible register number for function argument passing. */
+#define FUNCTION_ARG_REGNO_P(N) \
+((unsigned) (N) < MAX_ARC_PARM_REGS)
+
+/* The ROUND_ADVANCE* macros are local to this file. */
+/* Round SIZE up to a word boundary. */
+#define ROUND_ADVANCE(SIZE) \
+(((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* Round arg MODE/TYPE up to the next word boundary. */
+#define ROUND_ADVANCE_ARG(MODE, TYPE) \
+((MODE) == BLKmode \
+ ? ROUND_ADVANCE (int_size_in_bytes (TYPE)) \
+ : ROUND_ADVANCE (GET_MODE_SIZE (MODE)))
+
+/* Round CUM up to the necessary point for argument MODE/TYPE. */
+#define ROUND_ADVANCE_CUM(CUM, MODE, TYPE) \
+((((MODE) == BLKmode ? TYPE_ALIGN (TYPE) : GET_MODE_BITSIZE (MODE)) \
+ > BITS_PER_WORD) \
+ ? ((CUM) + 1 & ~1) \
+ : (CUM))
+
+/* Return boolean indicating arg of type TYPE and mode MODE will be passed in
+ a reg. This includes arguments that have to be passed by reference as the
+ pointer to them is passed in a reg if one is available (and that is what
+ we're given).
+ When passing arguments NAMED is always 1. When receiving arguments NAMED
+ is 1 for each argument except the last in a stdarg/varargs function. In
+ a stdarg function we want to treat the last named arg as named. In a
+ varargs function we want to treat the last named arg (which is
+ `__builtin_va_alist') as unnamed.
+ This macro is only used in this file. */
+extern int current_function_varargs;
+#define PASS_IN_REG_P(CUM, MODE, TYPE, NAMED) \
+((!current_function_varargs || (NAMED)) \
+ && (CUM) < MAX_ARC_PARM_REGS \
+ && ((ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE)) \
+ + ROUND_ADVANCE_ARG ((MODE), (TYPE)) \
+ <= MAX_ARC_PARM_REGS)))
+
+/* Determine where to put an argument 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). */
+/* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
+ and the rest are pushed. */
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
+(PASS_IN_REG_P ((CUM), (MODE), (TYPE), (NAMED)) \
+ ? gen_rtx (REG, (MODE), ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE))) \
+ : 0)
+
+/* A C expression for the number of words, at the beginning of an
+ argument, must be put in registers. The value must be zero for
+ arguments that are passed entirely in registers or that are entirely
+ pushed on the stack.
+
+ On some machines, certain arguments must be passed partially in
+ registers and partially in memory. On these machines, typically the
+ first @var{n} words of arguments are passed in registers, and the rest
+ on the stack. If a multi-word argument (a @code{double} or a
+ structure) crosses that boundary, its first few words must be passed
+ in registers and the rest must be pushed. This macro tells the
+ compiler when this occurs, and how many of the words should go in
+ registers. */
+#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
+
+/* A C expression that indicates when an argument must be passed by
+ reference. If nonzero for an argument, a copy of that argument is
+ made in memory and a pointer to the argument is passed instead of
+ the argument itself. The pointer is passed in whatever way is
+ appropriate for passing a pointer to that type. */
+/* All aggregates and arguments greater than 8 bytes are passed this way. */
+#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
+(TYPE \
+ && (AGGREGATE_TYPE_P (TYPE) \
+ || int_size_in_bytes (TYPE) > 8))
+
+/* A C expression that indicates when it is the called function's
+ responsibility to make copies of arguments passed by reference.
+ If the callee can determine that the argument won't be modified, it can
+ avoid the copy. */
+/* ??? We'd love to be able to use NAMED here. Unfortunately, it doesn't
+ include the last named argument so we keep track of the args ourselves. */
+
+#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
+FUNCTION_ARG_PASS_BY_REFERENCE ((CUM), (MODE), (TYPE), (NAMED))
+
+/* 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) \
+((CUM) = (ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE)) \
+ + ROUND_ADVANCE_ARG ((MODE), (TYPE))))
+
+/* If defined, a C expression that gives the alignment boundary, in bits,
+ of an argument with the specified mode and type. If it is not defined,
+ PARM_BOUNDARY is used for all arguments. */
+#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
+(((TYPE) ? TYPE_ALIGN (TYPE) : GET_MODE_BITSIZE (MODE)) <= PARM_BOUNDARY \
+ ? PARM_BOUNDARY \
+ : 2 * PARM_BOUNDARY)
+
+/* This macro offers an alternative
+ to using `__builtin_saveregs' and defining the macro
+ `EXPAND_BUILTIN_SAVEREGS'. Use it to store the anonymous register
+ arguments into the stack so that all the arguments appear to have
+ been passed consecutively on the stack. Once this is done, you
+ can use the standard implementation of varargs that works for
+ machines that pass all their arguments on the stack.
+
+ The argument ARGS_SO_FAR is the `CUMULATIVE_ARGS' data structure,
+ containing the values that obtain after processing of the named
+ arguments. The arguments MODE and TYPE describe the last named
+ argument--its machine mode and its data type as a tree node.
+
+ The macro implementation should do two things: first, push onto the
+ stack all the argument registers *not* used for the named
+ arguments, and second, store the size of the data thus pushed into
+ the `int'-valued variable whose name is supplied as the argument
+ PRETEND_SIZE. The value that you store here will serve as
+ additional offset for setting up the stack frame.
+
+ If the argument NO_RTL is nonzero, it means that the
+ arguments of the function are being analyzed for the second time.
+ This happens for an inline function, which is not actually
+ compiled until the end of the source file. The macro
+ `SETUP_INCOMING_VARARGS' should not generate any instructions in
+ this case. */
+
+#define SETUP_INCOMING_VARARGS(ARGS_SO_FAR, MODE, TYPE, PRETEND_SIZE, NO_RTL) \
+arc_setup_incoming_varargs(&ARGS_SO_FAR, MODE, TYPE, &PRETEND_SIZE, NO_RTL)
+
+/* Function results. */
+
+/* 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), 0)
+
+/* 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, 0)
+
+/* 1 if N is a possible register number for a function value
+ as seen by the caller. */
+/* ??? What about r1 in DI/DF values. */
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == 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. */
+#define RETURN_IN_MEMORY(TYPE) \
+(AGGREGATE_TYPE_P (TYPE) \
+ || int_size_in_bytes (TYPE) > 8 \
+ || TREE_ADDRESSABLE (TYPE))
+
+/* Tell GCC to use RETURN_IN_MEMORY. */
+#define DEFAULT_PCC_STRUCT_RETURN 0
+
+/* Register in which address to store a structure value
+ is passed to a function, or 0 to use `invisible' first argument. */
+#define STRUCT_VALUE 0
+
+/* Function entry and exit. */
+
+/* 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) \
+arc_output_function_prologue (FILE, SIZE)
+
+/* 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. */
+#define EXIT_IGNORE_STACK 0
+
+/* 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. */
+#define FUNCTION_EPILOGUE(FILE, SIZE) \
+arc_output_function_epilogue (FILE, SIZE)
+
+/* Epilogue delay slots. */
+#define DELAY_SLOTS_FOR_EPILOGUE arc_delay_slots_for_epilogue ()
+
+#define ELIGIBLE_FOR_EPILOGUE_DELAY(TRIAL, SLOTS_FILLED) \
+arc_eligible_for_epilogue_delay (TRIAL, SLOTS_FILLED)
+
+/* Output assembler code to FILE to increment profiler label # LABELNO
+ for profiling a function entry. */
+#define FUNCTION_PROFILER(FILE, LABELNO)
+
+/* Trampolines. */
+/* ??? This doesn't work yet because GCC will use as the address of a nested
+ function the address of the trampoline. We need to use that address
+ right shifted by 2. It looks like we'll need PSImode after all. :-( */
+
+/* Output assembler code for a block containing the constant parts
+ of a trampoline, leaving space for the variable parts. */
+/* On the ARC, the trampoline is quite simple as we have 32 bit immediate
+ constants.
+
+ mov r24,STATIC
+ j.nd FUNCTION
+*/
+#define TRAMPOLINE_TEMPLATE(FILE) \
+do { \
+ ASM_OUTPUT_INT (FILE, GEN_INT (0x631f7c00)); \
+ ASM_OUTPUT_INT (FILE, const0_rtx); \
+ ASM_OUTPUT_INT (FILE, GEN_INT (0x381f0000)); \
+ ASM_OUTPUT_INT (FILE, const0_rtx); \
+} while (0)
+
+/* Length in units of the trampoline for entering a nested function. */
+#define TRAMPOLINE_SIZE 16
+
+/* 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) \
+do { \
+ emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 4)), CXT); \
+ emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 12)), FNADDR); \
+ emit_insn (gen_flush_icache (validize_mem (gen_rtx (MEM, SImode, TRAMP)))); \
+} while (0)
+
+/* Library calls. */
+
+/* Generate calls to memcpy, memcmp and memset. */
+#define TARGET_MEM_FUNCTIONS
+
+/* Addressing modes, and classification of registers for them. */
+
+/* Maximum number of registers that can appear in a valid memory address. */
+/* The `ld' insn allows 2, but the `st' insn only allows 1. */
+#define MAX_REGS_PER_ADDRESS 1
+
+/* We have pre inc/dec (load/store with update). */
+#define HAVE_PRE_INCREMENT
+#define HAVE_PRE_DECREMENT
+
+/* Recognize any constant value that is a valid address. */
+#define CONSTANT_ADDRESS_P(X) \
+(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
+ || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST)
+
+/* Nonzero if the constant value X is a legitimate general operand.
+ We can handle any 32 or 64 bit constant. */
+/* "1" should work since the largest constant should be a 64 bit critter. */
+/* ??? Not sure what to do for 64x32 compiler. */
+#define LEGITIMATE_CONSTANT_P(X) 1
+
+/* 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. */
+
+#ifndef REG_OK_STRICT
+
+/* Nonzero if X is a hard reg that can be used as an index
+ or if it is a pseudo reg. */
+#define REG_OK_FOR_INDEX_P(X) \
+((unsigned) REGNO (X) - 29 >= FIRST_PSEUDO_REGISTER - 29)
+/* Nonzero if X is a hard reg that can be used as a base reg
+ or if it is a pseudo reg. */
+#define REG_OK_FOR_BASE_P(X) \
+((unsigned) REGNO (X) - 29 >= FIRST_PSEUDO_REGISTER - 29)
+
+#else
+
+/* Nonzero if X is a hard reg that can be used as an index. */
+#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+/* Nonzero if X is a hard reg that can be used as a base reg. */
+#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (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 `ld' insn allows [reg],[reg+shimm],[reg+limm],[reg+reg],[limm]
+ but the `st' insn only allows [reg],[reg+shimm],[limm].
+ The only thing we can do is only allow the most strict case `st' and hope
+ other parts optimize out the restrictions for `ld'. */
+
+/* local to this file */
+#define RTX_OK_FOR_BASE_P(X) \
+(REG_P (X) && REG_OK_FOR_BASE_P (X))
+
+/* local to this file */
+#define RTX_OK_FOR_INDEX_P(X) \
+(0 && /*???*/ REG_P (X) && REG_OK_FOR_INDEX_P (X))
+
+/* local to this file */
+/* ??? Loads can handle any constant, stores can only handle small ones. */
+#define RTX_OK_FOR_OFFSET_P(X) \
+(GET_CODE (X) == CONST_INT && SMALL_INT (INTVAL (X)))
+
+#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X) \
+(GET_CODE (X) == PLUS \
+ && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \
+ && (RTX_OK_FOR_INDEX_P (XEXP (X, 1)) \
+ || RTX_OK_FOR_OFFSET_P (XEXP (X, 1))))
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+{ if (RTX_OK_FOR_BASE_P (X)) \
+ goto ADDR; \
+ if (LEGITIMATE_OFFSET_ADDRESS_P ((MODE), (X))) \
+ goto ADDR; \
+ if (GET_CODE (X) == CONST_INT && LARGE_INT (INTVAL (X))) \
+ goto ADDR; \
+ if (GET_CODE (X) == SYMBOL_REF \
+ || GET_CODE (X) == LABEL_REF \
+ || GET_CODE (X) == CONST) \
+ goto ADDR; \
+ if ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == PRE_INC) \
+ /* We're restricted here by the `st' insn. */ \
+ && RTX_OK_FOR_BASE_P (XEXP ((X), 0))) \
+ goto ADDR; \
+}
+
+/* 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. */
+
+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)
+
+/* Go to LABEL if ADDR (a legitimate address expression)
+ has an effect that depends on the machine mode it is used for. */
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
+{ if (GET_CODE (ADDR) == PRE_DEC) \
+ goto LABEL; \
+ if (GET_CODE (ADDR) == PRE_INC) \
+ goto LABEL; \
+}
+
+/* Condition code usage. */
+
+/* Some insns set all condition code flags, some only set the ZNC flags, and
+ some only set the ZN flags. */
+
+#define EXTRA_CC_MODES CCZNCmode, CCZNmode
+
+#define EXTRA_CC_NAMES "CCZNC", "CCZN"
+
+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
+ return the mode to be used for the comparison. */
+extern enum machine_mode arc_select_cc_mode ();
+#define SELECT_CC_MODE(OP, X, Y) \
+arc_select_cc_mode (OP, X, Y)
+
+/* Return non-zero if SELECT_CC_MODE will never return MODE for a
+ floating point inequality comparison. */
+#define REVERSIBLE_CC_MODE(MODE) 1 /*???*/
+
+/* Costs. */
+
+/* An insn is define to cost 4 "units", and we work from there.
+ COSTS_N_INSNS (N) is defined as (N) * 4 - 2 so that seems reasonable.
+ Some values are supposed to be defined relative to each other and thus
+ aren't necessarily related to COSTS_N_INSNS. */
+
+/* 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. */
+/* Small integers are as cheap as registers. 4 byte values can be fetched
+ as immediate constants - let's give that the cost of an extra insn. */
+#define CONST_COSTS(X, CODE, OUTER_CODE) \
+ case CONST_INT : \
+ if (SMALL_INT (INTVAL (X))) \
+ return 0; \
+ /* fall through */ \
+ case CONST : \
+ case LABEL_REF : \
+ case SYMBOL_REF : \
+ return 4; \
+ case CONST_DOUBLE : \
+ { \
+ rtx high, low; \
+ split_double (X, &high, &low); \
+ return 4 * (!SMALL_INT (INTVAL (high)) \
+ + !SMALL_INT (INTVAL (low))); \
+ }
+
+/* Compute the cost of an address. */
+#define ADDRESS_COST(ADDR) (REG_P (ADDR) ? 1 : arc_address_cost (ADDR))
+
+/* Compute extra cost of moving data between one register class
+ and another. */
+#define REGISTER_MOVE_COST(CLASS1, CLASS2) 2
+
+/* Compute the cost of moving data between registers and memory. */
+/* Memory is 3 times as expensive as registers.
+ ??? Is that the right way to look at it? */
+#define MEMORY_MOVE_COST(MODE) \
+(GET_MODE_SIZE (MODE) <= UNITS_PER_WORD ? 6 : 12)
+
+/* The cost of a branch insn. */
+/* ??? What's the right value here? Branches are certainly more
+ expensive than reg->reg moves. */
+#define BRANCH_COST 2
+
+/* Provide the costs of a rtl expression. This is in the body of a
+ switch on CODE. The purpose for the cost of MULT is to encourage
+ `synth_mult' to find a synthetic multiply when reasonable.
+
+ If we need more than 12 insns to do a multiply, then go out-of-line,
+ since the call overhead will be < 10% of the cost of the multiply. */
+#define RTX_COSTS(X, CODE, OUTER_CODE) \
+ case ASHIFT : \
+ case ASHIFTRT : \
+ case LSHIFTRT : \
+ if (TARGET_SHIFTER) \
+ return COSTS_N_INSNS (1); \
+ if (GET_CODE (XEXP ((X), 1)) != CONST_INT) \
+ return COSTS_N_INSNS (16); \
+ return COSTS_N_INSNS (INTVAL (XEXP ((X), 1)));
+
+/* Nonzero if access to memory by bytes is slow and undesirable.
+ For RISC chips, it means that access to memory by bytes is no
+ better than access by words when possible, so grab a whole word
+ and maybe make use of that. */
+#define SLOW_BYTE_ACCESS 1
+
+/* Define this macro if it is as good or better to call a constant
+ function address than to call an address kept in a register. */
+/* On the ARC, calling through registers is slow. */
+#define NO_FUNCTION_CSE
+
+/* Define this macro if it is as good or better for a function to call
+ itself with an explicit address than to call an address kept in a
+ register. */
+/* On the ARC, calling through registers is slow. */
+#define NO_RECURSIVE_FUNCTION_CSE
+
+/* Section selection. */
+/* WARNING: These section names also appear in dwarfout.c. */
+
+/* The names of the text, data, and readonly-data sections are runtime
+ selectable. */
+
+#define ARC_SECTION_FORMAT "\t.section %s"
+#define ARC_DEFAULT_TEXT_SECTION ".text"
+#define ARC_DEFAULT_DATA_SECTION ".data"
+#define ARC_DEFAULT_RODATA_SECTION ".rodata"
+
+extern char *arc_text_section,*arc_data_section,*arc_rodata_section;
+
+/* initfini.c uses this in an asm. */
+#if defined (CRT_INIT) || defined (CRT_FINI)
+#define TEXT_SECTION_ASM_OP "\t.section .text"
+#else
+#define TEXT_SECTION_ASM_OP arc_text_section /*"\t.section .text"*/
+#endif
+#define DATA_SECTION_ASM_OP arc_data_section /*"\t.section .data"*/
+
+#undef CONST_SECTION_ASM_OP
+#define CONST_SECTION_ASM_OP arc_rodata_section /*"\t.section .rodata"*/
+
+#define BSS_SECTION_ASM_OP "\t.section .bss"
+
+/* Define this macro if jump tables (for tablejump insns) should be
+ output in the text section, along with the assembler instructions.
+ Otherwise, the readonly data section is used.
+ This macro is irrelevant if there is no separate readonly data section. */
+/*#define JUMP_TABLES_IN_TEXT_SECTION*/
+
+/* 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 or other node is created.
+ 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 store 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). */
+
+/* On the ARC, function addresses are not the same as normal addresses.
+ Branch to absolute address insns take an address that is right-shifted
+ by 2. We encode the fact that we have a function here, and then emit a
+ special assembler op when outputting the address. */
+#define ENCODE_SECTION_INFO(DECL) \
+do { \
+ if (TREE_CODE (DECL) == FUNCTION_DECL) \
+ SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; \
+} while (0)
+
+/* Decode SYM_NAME and store the real name part in VAR, sans
+ the characters that encode section info. Define this macro if
+ ENCODE_SECTION_INFO alters the symbol's name string. */
+/*#define STRIP_NAME_ENCODING(VAR, SYM_NAME)*/
+
+/* For DWARF. Marginally different than default so output is "prettier"
+ (and consistent with above). */
+#define PUSHSECTION_FORMAT "\t%s %s\n"
+
+/* Tell crtstuff.c we're using ELF. */
+#define OBJECT_FORMAT_ELF
+
+/* PIC */
+
+/* The register number of the register used to address a table of static
+ data addresses in memory. In some cases this register is defined by a
+ processor's ``application binary interface'' (ABI). When this macro
+ is defined, RTL is generated for this register once, as with the stack
+ pointer and frame pointer registers. If this macro is not defined, it
+ is up to the machine-dependent files to allocate such a register (if
+ necessary). */
+#define PIC_OFFSET_TABLE_REGNUM 26
+
+/* Define this macro if the register defined by PIC_OFFSET_TABLE_REGNUM is
+ clobbered by calls. Do not define this macro if PIC_OFFSET_TABLE_REGNUM
+ is not defined. */
+/* This register is call-saved on the ARC. */
+/*#define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED*/
+
+/* By generating position-independent code, when two different programs (A
+ and B) share a common library (libC.a), the text of the library can be
+ shared whether or not the library is linked at the same address for both
+ programs. In some of these environments, position-independent code
+ requires not only the use of different addressing modes, but also
+ special code to enable the use of these addressing modes.
+
+ 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 INITIALIZE_PIC arc_initialize_pic ()
+#define FINALIZE_PIC arc_finalize_pic ()
+
+/* A C expression that is nonzero if X is a legitimate immediate
+ operand on the target machine when generating position independent code.
+ You can assume that X satisfies CONSTANT_P, so you need not
+ check this. You can also assume `flag_pic' is true, so you need not
+ check it either. You need not define this macro if all constants
+ (including SYMBOL_REF) can be immediate operands when generating
+ position independent code. */
+/*#define LEGITIMATE_PIC_OPERAND_P(X)*/
+
+/* Control the assembler format that we output. */
+
+/* Output at beginning of assembler file. */
+extern void arc_asm_file_start ();
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) arc_asm_file_start (FILE)
+
+/* A C statement to output assembler commands which will identify the
+ object file as having been compiled with GNU CC (or another GNU
+ compiler). */
+#undef ASM_IDENTIFY_GCC
+#define ASM_IDENTIFY_GCC(FILE) /* nothing */
+
+/* Needed because we define ASM_IDENTIFY_GCC. */
+#define ASM_IDENTIFY_LANGUAGE(FILE) output_lang_identify (FILE)
+
+/* A C string constant describing how to begin a comment in the target
+ assembler language. The compiler assumes that the comment will
+ end at the end of the line. */
+#define ASM_COMMENT_START ";"
+
+/* Output to assembler file text saying following lines
+ may contain character constants, extra white space, comments, etc. */
+#define ASM_APP_ON ""
+
+/* Output to assembler file text saying following lines
+ no longer contain unusual constructs. */
+#define ASM_APP_OFF ""
+
+/* This is how to output an assembler line defining a `char' constant. */
+#define ASM_OUTPUT_CHAR(FILE, VALUE) \
+( fprintf (FILE, "\t.byte\t"), \
+ output_addr_const (FILE, (VALUE)), \
+ fprintf (FILE, "\n"))
+
+/* This is how to output an assembler line defining a `short' constant. */
+#define ASM_OUTPUT_SHORT(FILE, VALUE) \
+( fprintf (FILE, "\t.hword\t"), \
+ output_addr_const (FILE, (VALUE)), \
+ fprintf (FILE, "\n"))
+
+/* This is how to output an assembler line defining an `int' constant.
+ We also handle symbol output here. Code addresses must be right shifted
+ by 2 because that's how the jump instruction wants them. */
+#define ASM_OUTPUT_INT(FILE, VALUE) \
+do { \
+ fprintf (FILE, "\t.word\t"); \
+ if ((GET_CODE (VALUE) == SYMBOL_REF && SYMBOL_REF_FLAG (VALUE)) \
+ || GET_CODE (VALUE) == LABEL_REF) \
+ { \
+ fprintf (FILE, "%%st("); \
+ output_addr_const (FILE, (VALUE)); \
+ fprintf (FILE, ")"); \
+ } \
+ else \
+ output_addr_const (FILE, (VALUE)); \
+ fprintf (FILE, "\n"); \
+} while (0)
+
+/* This is how to output an assembler line defining a `float' constant. */
+#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
+{ \
+ long t; \
+ char str[30]; \
+ REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \
+ fprintf (FILE, "\t.word\t0x%lx %s %s\n", \
+ t, ASM_COMMENT_START, str); \
+}
+
+/* This is how to output an assembler line defining a `double' constant. */
+#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
+{ \
+ long t[2]; \
+ char str[30]; \
+ REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \
+ fprintf (FILE, "\t.word\t0x%lx %s %s\n\t.word\t0x%lx\n", \
+ t[0], ASM_COMMENT_START, str, t[1]); \
+}
+
+/* This is how to output an assembler line for a numeric constant byte. */
+#define ASM_BYTE_OP ".byte"
+#define ASM_OUTPUT_BYTE(FILE, VALUE) \
+ fprintf (FILE, "\t%s\t0x%x\n", ASM_BYTE_OP, (VALUE))
+
+/* The assembler's parentheses characters. */
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
+
+/* 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) \
+do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
+
+/* 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) \
+do { \
+ fputs ("\t.global\t", FILE); \
+ assemble_name (FILE, NAME); \
+ fputs ("\n", FILE); \
+} while (0)
+
+/* A C statement (sans semicolon) to output on FILE an assembler pseudo-op to
+ declare a library function name external. The name of the library function
+ is given by SYMREF, which has type RTX and is a SYMBOL_REF. */
+#if 0
+/* On the ARC we want to have libgcc's for multiple cpus in one binary.
+ We can't use `assemble_name' here as that will call ASM_OUTPUT_LABELREF
+ and we'll get another suffix added on if -mmangle-cpu. */
+extern char *arc_mangle_cpu;
+#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, SYMREF) \
+do { \
+ if (TARGET_MANGLE_CPU_LIBGCC) \
+ { \
+ fprintf (FILE, "\t.rename\t_%s, _%s%s\n", \
+ XSTR (SYMREF, 0), XSTR (SYMREF, 0), \
+ arc_mangle_suffix); \
+ } \
+} while (0)
+#endif
+
+/* This is how to output a reference to a user-level label named NAME.
+ `assemble_name' uses this. */
+/* We mangle all user labels to provide protection from linking code
+ compiled for different cpus. */
+/* We work around a dwarfout.c deficiency by watching for labels from it and
+ not adding the '_' prefix nor the cpu suffix. There is a comment in
+ dwarfout.c that says it should be using ASM_OUTPUT_INTERNAL_LABEL. */
+extern char *arc_mangle_cpu;
+#define ASM_OUTPUT_LABELREF(FILE, NAME) \
+do { \
+ if ((NAME)[0] == '.' && (NAME)[1] == 'L') \
+ fprintf (FILE, "%s", NAME); \
+ else \
+ { \
+ fputc ('_', FILE); \
+ if (TARGET_MANGLE_CPU && arc_mangle_cpu != NULL) \
+ fprintf (FILE, "%s_", arc_mangle_cpu); \
+ fprintf (FILE, "%s", NAME); \
+ } \
+} while (0)
+
+/* This is how to output a definition of 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) \
+do { \
+ arc_ccfsm_at_label (PREFIX, NUM); \
+ fprintf (FILE, ".%s%d:\n", PREFIX, NUM); \
+} 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)))
+
+/* Assembler pseudo-op to equate one value with another. */
+/* ??? This is needed because dwarfout.c provides a default definition too
+ late for defaults.h (which contains the default definition of ASM_OUTPUT_DEF
+ that we use). */
+#define SET_ASM_OP ".set"
+
+/* A C statement (sans semicolon) to output an element in the table of
+ global constructors. */
+#undef ASM_OUTPUT_CONSTRUCTOR
+#define ASM_OUTPUT_CONSTRUCTOR(FILE, NAME) \
+do { \
+ ctors_section (); \
+ fprintf (FILE, "\t.word\t%%st("); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, ")\n"); \
+} while (0)
+
+/* A C statement (sans semicolon) to output an element in the table of
+ global destructors. */
+#undef ASM_OUTPUT_DESTRUCTOR
+#define ASM_OUTPUT_DESTRUCTOR(FILE, NAME) \
+do { \
+ dtors_section (); \
+ fprintf (FILE, "\t.word\t%%st("); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, ")\n"); \
+} while (0)
+
+/* How to refer to registers in assembler output.
+ This sequence is indexed by compiler's hard-register-number (see above). */
+#define REGISTER_NAMES \
+{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
+ "r24", "r25", "r26", "fp", "sp", "ilink1", "ilink2", "blink", \
+ "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", \
+ "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", \
+ "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", \
+ "r56", "r57", "r58", "r59", "lp_count", "cc"}
+
+/* Entry to the insn conditionalizer. */
+#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
+arc_final_prescan_insn (INSN, OPVEC, NOPERANDS)
+
+/* A C expression which evaluates to true if CODE is a valid
+ punctuation character for use in the `PRINT_OPERAND' macro. */
+extern char arc_punct_chars[];
+#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
+arc_punct_chars[(unsigned char) (CHAR)]
+
+/* 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.
+ For `%' followed by punctuation, CODE is the punctuation and X is null. */
+#define PRINT_OPERAND(FILE, X, CODE) \
+arc_print_operand (FILE, X, CODE)
+
+/* A C compound statement to output to stdio stream STREAM the
+ assembler syntax for an instruction operand that is a memory
+ reference whose address is ADDR. ADDR is an RTL expression.
+
+ On some machines, the syntax for a symbolic address depends on
+ the section that the address refers to. On these machines,
+ define the macro `ENCODE_SECTION_INFO' to store the information
+ into the `symbol_ref', and then check for it here. */
+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
+arc_print_operand_address (FILE, ADDR)
+
+/* This is how to output an element of a case-vector that is absolute. */
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
+do { \
+ char label[30]; \
+ ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \
+ fprintf (FILE, "\t.word %%st("); \
+ assemble_name (FILE, label); \
+ fprintf (FILE, ")\n"); \
+} while (0)
+
+/* This is how to output an element of a case-vector that is relative. */
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
+do { \
+ char label[30]; \
+ ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \
+ fprintf (FILE, "\t.word %%st("); \
+ assemble_name (FILE, label); \
+ fprintf (FILE, "-"); \
+ ASM_GENERATE_INTERNAL_LABEL (label, "L", REL); \
+ assemble_name (FILE, label); \
+ fprintf (FILE, ")\n"); \
+} while (0)
+
+/* A C expression to output text to align the location counter in the way
+ that is desirable at the beginning of a loop. */
+/* On the ARC, align loops to 32 byte boundaries (cache line size)
+ if -malign-loops. */
+#define ASM_OUTPUT_LOOP_ALIGN(FILE) \
+do { if (TARGET_ALIGN_LOOPS) ASM_OUTPUT_SKIP (FILE, 5); } while (0)
+
+/* 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) \
+do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", 1 << (LOG)); } while (0)
+
+/* Debugging information. */
+
+/* Generate DBX and DWARF debugging information. */
+#define DBX_DEBUGGING_INFO
+#define DWARF_DEBUGGING_INFO
+
+/* Prefer STABS (for now). */
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+/* How to renumber registers for dbx and gdb. */
+#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+
+/* Turn off splitting of long stabs. */
+#define DBX_CONTIN_LENGTH 0
+
+/* Miscellaneous. */
+
+/* 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. */
+/* It's not clear what PIC will look like or whether we want to use -fpic
+ for the embedded form currently being talked about. For now require -fpic
+ to get pc relative switch tables. */
+/*#define CASE_VECTOR_PC_RELATIVE*/
+
+/* Define if operations between registers always perform the operation
+ on the full register even if a narrower mode is specified. */
+#define WORD_REGISTER_OPERATIONS
+
+/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
+ will either zero-extend or sign-extend. The value of this macro should
+ be the code that says which one of the two operations is implicitly
+ done, NIL if none. */
+#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
+
+/* Specify the tree operation to be used to convert reals to integers. */
+#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
+
+/* Max number of bytes we can move from memory to memory
+ in one reasonably fast instruction. */
+#define MOVE_MAX 4
+
+/* Define this to be nonzero if shift instructions ignore all but the low-order
+ few bits. */
+#define SHIFT_COUNT_TRUNCATED 1
+
+/* 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
+
+/* 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. */
+/* ??? The arc doesn't have full 32 bit pointers, but making this PSImode has
+ it's own problems (you have to add extendpsisi2 and trucnsipsi2 but how does
+ one do it without getting excess code?). Try to avoid it. */
+#define Pmode SImode
+
+/* A function address in a call instruction. */
+#define FUNCTION_MODE SImode
+
+/* 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 TYPE. */
+extern int arc_valid_machine_attribute ();
+#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
+arc_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
+
+/* A C expression that returns 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). */
+extern int arc_comp_type_attributes ();
+#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
+arc_comp_type_attributes (TYPE1, TYPE2)
+
+/* Give newly defined TYPE some default attributes. */
+extern void arc_set_default_type_attributes ();
+#define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \
+arc_set_default_type_attributes (TYPE)
+
+/* Define this if the target system supports the function
+ atexit from the ANSI C standard. If this is not defined,
+ and INIT_SECTION_ASM_OP is not defined, a default
+ exit function will be provided to support C++. */
+#define HAVE_ATEXIT
+
+/* alloca should avoid clobbering the old register save area. */
+/* ??? Not defined in tm.texi. */
+#define SETJMP_VIA_SAVE_AREA
+
+/* 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 *arc_compare_op0, *arc_compare_op1;
+
+/* Define the function that build the compare insn for scc and bcc. */
+extern struct rtx_def *gen_compare_reg ();
+
+/* Declarations for various fns used in the .md file. */
+extern char *output_shift ();
+
+/* ARC function types. */
+enum arc_function_type {
+ ARC_FUNCTION_UNKNOWN, ARC_FUNCTION_NORMAL,
+ /* These are interrupt handlers. The name corresponds to the register
+ name that contains the return address. */
+ ARC_FUNCTION_ILINK1, ARC_FUNCTION_ILINK2
+};
+#define ARC_INTERRUPT_P(TYPE) \
+((TYPE) == ARC_FUNCTION_ILINK1 || (TYPE) == ARC_FUNCTION_ILINK2)
+/* Compute the type of a function from its DECL. */
+enum arc_function_type arc_compute_function_type ();
diff --git a/gnu/usr.bin/gcc/config/arc/arc.md b/gnu/usr.bin/gcc/config/arc/arc.md
new file mode 100644
index 00000000000..328b1ebd991
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arc/arc.md
@@ -0,0 +1,1630 @@
+;; Machine description of the Argonaut ARC cpu for GNU C compiler
+;; Copyright (C) 1994, 1997 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.
+
+;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
+
+;; ??? This is an old port, and is undoubtedly suffering from bit rot.
+
+;; Insn type. Used to default other attribute values.
+
+(define_attr "type"
+ "move,load,store,cmove,unary,binary,compare,shift,mul,uncond_branch,branch,call,call_no_delay_slot,multi,misc"
+ (const_string "binary"))
+
+;; Length (in # of insns, long immediate constants counted too).
+;; ??? There's a nasty interaction between the conditional execution fsm
+;; and insn lengths: insns with shimm values cannot be conditionally executed.
+(define_attr "length" ""
+ (cond [(eq_attr "type" "load")
+ (if_then_else (match_operand 1 "long_immediate_loadstore_operand" "")
+ (const_int 2) (const_int 1))
+
+ (eq_attr "type" "store")
+ (if_then_else (match_operand 0 "long_immediate_loadstore_operand" "")
+ (const_int 2) (const_int 1))
+
+ (eq_attr "type" "move,unary,compare")
+ (if_then_else (match_operand 1 "long_immediate_operand" "")
+ (const_int 2) (const_int 1))
+
+ (eq_attr "type" "binary,mul")
+ (if_then_else (match_operand 2 "long_immediate_operand" "")
+ (const_int 2) (const_int 1))
+
+ (eq_attr "type" "cmove")
+ (if_then_else (match_operand 2 "register_operand" "")
+ (const_int 1) (const_int 2))
+
+ (eq_attr "type" "multi") (const_int 2)
+ ]
+
+ (const_int 1)))
+
+;; The length here is the length of a single asm. Unfortunately it might be
+;; 1 or 2 so we must allow for 2. That's ok though. How often will users
+;; lament asm's not being put in delay slots?
+(define_asm_attributes
+ [(set_attr "length" "2")
+ (set_attr "type" "multi")])
+
+;; Condition codes: this one is used by final_prescan_insn to speed up
+;; conditionalizing instructions. It saves having to scan the rtl to see if
+;; it uses or alters the condition codes.
+
+;; USE: This insn uses the condition codes (eg: a conditional branch).
+;; CANUSE: This insn can use the condition codes (for conditional execution).
+;; SET: All condition codes are set by this insn.
+;; SET_ZN: the Z and N flags are set by this insn.
+;; SET_ZNC: the Z, N, and C flags are set by this insn.
+;; CLOB: The condition codes are set to unknown values by this insn.
+;; NOCOND: This insn can't use and doesn't affect the condition codes.
+
+(define_attr "cond" "use,canuse,set,set_zn,set_znc,clob,nocond"
+ (cond [(and (eq_attr "type" "unary,binary,move")
+ (eq_attr "length" "1"))
+ (const_string "canuse")
+
+ (eq_attr "type" "compare")
+ (const_string "set")
+
+ (eq_attr "type" "cmove,branch")
+ (const_string "use")
+
+ (eq_attr "type" "multi,misc")
+ (const_string "clob")
+ ]
+
+ (const_string "nocond")))
+
+;; Delay slots.
+
+(define_attr "in_delay_slot" "false,true"
+ (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
+ (const_string "false")
+ ]
+
+ (if_then_else (eq_attr "length" "1")
+ (const_string "true")
+ (const_string "false"))))
+
+(define_delay (eq_attr "type" "call")
+ [(eq_attr "in_delay_slot" "true")
+ (eq_attr "in_delay_slot" "true")
+ (eq_attr "in_delay_slot" "true")])
+
+(define_delay (eq_attr "type" "branch,uncond_branch")
+ [(eq_attr "in_delay_slot" "true")
+ (eq_attr "in_delay_slot" "true")
+ (eq_attr "in_delay_slot" "true")])
+
+;; Function units of the ARC
+
+;; (define_function_unit {name} {num-units} {n-users} {test}
+;; {ready-delay} {issue-delay} [{conflict-list}])
+
+;; 1) A conditional jump cannot immediately follow the insn setting the flags.
+;; This isn't a complete solution as it doesn't come with guarantees. That
+;; is done in the branch patterns and in arc_print_operand. This exists to
+;; avoid inserting a nop when we can.
+(define_function_unit "compare" 1 0 (eq_attr "type" "compare") 2 2 [(eq_attr "type" "branch")])
+
+;; 2) References to loaded registers should wait a cycle.
+
+;; Memory with load-delay of 1 (i.e., 2 cycle load).
+(define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0)
+
+;; Units that take one cycle do not need to be specified.
+
+;; Move instructions.
+
+(define_expand "movqi"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (match_operand:QI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* Everything except mem = const or mem = mem can be done easily. */
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (QImode, operands[1]);
+}")
+
+(define_insn "*movqi_insn"
+ [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,m")
+ (match_operand:QI 1 "move_src_operand" "rI,Ji,m,r"))]
+;; ??? Needed?
+ "register_operand (operands[0], QImode)
+ || register_operand (operands[1], QImode)"
+ "@
+ mov%? %0,%1
+ mov%? %0,%1
+ ldb%U1%V1 %0,%1
+ stb%U0%V0 %1,%0"
+ [(set_attr "type" "move,move,load,store")])
+
+;; ??? This may never match since there's no cmpqi insn.
+
+(define_insn "*movqi_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CCZN
+ (sign_extend:SI (match_operand:QI 1 "move_src_operand" "rIJi"))
+ (const_int 0)))
+ (set (match_operand:QI 0 "move_dest_operand" "=r")
+ (match_dup 1))]
+ ""
+ "mov%?.f %0,%1"
+ [(set_attr "type" "move")
+ (set_attr "cond" "set_zn")])
+
+(define_expand "movhi"
+ [(set (match_operand:HI 0 "general_operand" "")
+ (match_operand:HI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* Everything except mem = const or mem = mem can be done easily. */
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (HImode, operands[1]);
+}")
+
+(define_insn "*movhi_insn"
+ [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,m")
+ (match_operand:HI 1 "move_src_operand" "rI,Ji,m,r"))]
+ "register_operand (operands[0], HImode)
+ || register_operand (operands[1], HImode)"
+ "@
+ mov%? %0,%1
+ mov%? %0,%1
+ ldw%U1%V1 %0,%1
+ stw%U0%V0 %1,%0"
+ [(set_attr "type" "move,move,load,store")])
+
+;; ??? Will this ever match?
+
+(define_insn "*movhi_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CCZN
+ (sign_extend:SI (match_operand:HI 1 "move_src_operand" "rIJi"))
+ (const_int 0)))
+ (set (match_operand:HI 0 "move_dest_operand" "=r")
+ (match_dup 1))]
+;; ??? Needed?
+ "register_operand (operands[0], HImode)
+ || register_operand (operands[1], HImode)"
+ "mov%?.f %0,%1"
+ [(set_attr "type" "move")
+ (set_attr "cond" "set_zn")])
+
+(define_expand "movsi"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (match_operand:SI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* Everything except mem = const or mem = mem can be done easily. */
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (SImode, operands[1]);
+}")
+
+(define_insn "*movsi_insn"
+ [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,m")
+ (match_operand:SI 1 "move_src_operand" "rI,GJi,m,r"))]
+ "register_operand (operands[0], SImode)
+ || register_operand (operands[1], SImode)"
+ "@
+ mov%? %0,%1
+ mov%? %0,%S1
+ ld%U1%V1 %0,%1
+ st%U0%V0 %1,%0"
+ [(set_attr "type" "move,move,load,store")])
+
+(define_insn "*movsi_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CCZN
+ (match_operand:SI 1 "move_src_operand" "rIJi")
+ (const_int 0)))
+ (set (match_operand:SI 0 "move_dest_operand" "=r")
+ (match_dup 1))]
+ "register_operand (operands[0], SImode)
+ || register_operand (operands[1], SImode)"
+ "mov%?.f %0,%S1"
+ [(set_attr "type" "move")
+ (set_attr "cond" "set_zn")])
+
+(define_expand "movdi"
+ [(set (match_operand:DI 0 "general_operand" "")
+ (match_operand:DI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* Everything except mem = const or mem = mem can be done easily. */
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (DImode, operands[1]);
+}")
+
+(define_insn "*movdi_insn"
+ [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,m")
+ (match_operand:DI 1 "move_double_src_operand" "r,HK,m,r"))]
+ "register_operand (operands[0], DImode)
+ || register_operand (operands[1], DImode)"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0 :
+ /* We normally copy the low-numbered register first. However, if
+ the first register operand 0 is the same as the second register of
+ operand 1, we must copy in the opposite order. */
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"mov %R0,%R1\;mov %0,%1\";
+ else
+ return \"mov %0,%1\;mov %R0,%R1\";
+ case 1 :
+ return \"mov %0,%L1\;mov %R0,%H1\";
+ case 2 :
+ /* If the low-address word is used in the address, we must load it
+ last. Otherwise, load it first. Note that we cannot have
+ auto-increment in that case since the address register is known to be
+ dead. */
+ if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
+ operands [1], 0))
+ return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
+ else
+ return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
+ case 3 :
+ return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
+ }
+}"
+ [(set_attr "type" "move,move,load,store")
+ ;; ??? The ld/st values could be 4 if it's [reg,bignum].
+ (set_attr "length" "2,4,2,2")])
+
+;(define_expand "movdi"
+; [(set (match_operand:DI 0 "general_operand" "")
+; (match_operand:DI 1 "general_operand" ""))]
+; ""
+; "
+;{
+; /* Flow doesn't understand that this is effectively a DFmode move.
+; It doesn't know that all of `operands[0]' is set. */
+; emit_insn (gen_rtx (CLOBBER, VOIDmode, operands[0]));
+;
+; /* Emit insns that movsi_insn can handle. */
+; emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DImode),
+; operand_subword (operands[1], 0, 0, DImode)));
+; emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DImode),
+; operand_subword (operands[1], 1, 0, DImode)));
+; DONE;
+;}")
+
+;; Floating point move insns.
+
+(define_expand "movsf"
+ [(set (match_operand:SF 0 "general_operand" "")
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* Everything except mem = const or mem = mem can be done easily. */
+
+#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ operands[1] = force_const_mem (SFmode, operands[1]);
+#endif
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (SFmode, operands[1]);
+}")
+
+(define_insn "*movsf_insn"
+ [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
+ (match_operand:SF 1 "move_src_operand" "r,E,m,r"))]
+ "register_operand (operands[0], SFmode)
+ || register_operand (operands[1], SFmode)"
+ "@
+ mov%? %0,%1
+ mov%? %0,%1 ; %A1
+ ld%U1%V1 %0,%1
+ st%U0%V0 %1,%0"
+ [(set_attr "type" "move,move,load,store")])
+
+(define_expand "movdf"
+ [(set (match_operand:DF 0 "general_operand" "")
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* Everything except mem = const or mem = mem can be done easily. */
+
+#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ operands[1] = force_const_mem (DFmode, operands[1]);
+#endif
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (DFmode, operands[1]);
+}")
+
+(define_insn "*movdf_insn"
+ [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
+ (match_operand:DF 1 "move_double_src_operand" "r,E,m,r"))]
+ "register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode)"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0 :
+ /* We normally copy the low-numbered register first. However, if
+ the first register operand 0 is the same as the second register of
+ operand 1, we must copy in the opposite order. */
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"mov %R0,%R1\;mov %0,%1\";
+ else
+ return \"mov %0,%1\;mov %R0,%R1\";
+ case 1 :
+ return \"mov %0,%L1\;mov %R0,%H1 ; %A1\";
+ case 2 :
+ /* If the low-address word is used in the address, we must load it
+ last. Otherwise, load it first. Note that we cannot have
+ auto-increment in that case since the address register is known to be
+ dead. */
+ if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
+ operands [1], 0))
+ return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
+ else
+ return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
+ case 3 :
+ return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
+ }
+}"
+ [(set_attr "type" "move,move,load,store")
+ ;; ??? The ld/st values could be 4 if it's [reg,bignum].
+ (set_attr "length" "2,4,2,2")])
+
+;(define_expand "movdf"
+; [(set (match_operand:DF 0 "general_operand" "")
+; (match_operand:DF 1 "general_operand" ""))]
+; ""
+; "
+;{
+; /* Flow doesn't understand that this is effectively a DFmode move.
+; It doesn't know that all of `operands[0]' is set. */
+; emit_insn (gen_rtx (CLOBBER, VOIDmode, operands[0]));
+;
+; /* Emit insns that movsi_insn can handle. */
+; emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DFmode),
+; operand_subword (operands[1], 0, 0, DFmode)));
+; emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DFmode),
+; operand_subword (operands[1], 1, 0, DFmode)));
+; DONE;
+;}")
+
+;; Load/Store with update instructions.
+;;
+;; Some of these we can get by using pre-decrement or pre-increment, but the
+;; hardware can also do cases where the increment is not the size of the
+;; object.
+;;
+;; In all these cases, we use operands 0 and 1 for the register being
+;; incremented because those are the operands that local-alloc will
+;; tie and these are the pair most likely to be tieable (and the ones
+;; that will benefit the most).
+;;
+;; We use match_operator here because we need to know whether the memory
+;; object is volatile or not.
+
+(define_insn "*loadqi_update"
+ [(set (match_operand:QI 3 "register_operand" "=r,r")
+ (match_operator:QI 4 "load_update_operand"
+ [(match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
+ (set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "ldb.a%V4 %3,[%0,%2]"
+ [(set_attr "type" "load,load")
+ (set_attr "length" "1,2")])
+
+(define_insn "*load_zeroextendqisi_update"
+ [(set (match_operand:SI 3 "register_operand" "=r,r")
+ (zero_extend:SI (match_operator:QI 4 "load_update_operand"
+ [(match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
+ (set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "ldb.a%V4 %3,[%0,%2]"
+ [(set_attr "type" "load,load")
+ (set_attr "length" "1,2")])
+
+(define_insn "*load_signextendqisi_update"
+ [(set (match_operand:SI 3 "register_operand" "=r,r")
+ (sign_extend:SI (match_operator:QI 4 "load_update_operand"
+ [(match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
+ (set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "ldb.x.a%V4 %3,[%0,%2]"
+ [(set_attr "type" "load,load")
+ (set_attr "length" "1,2")])
+
+(define_insn "*storeqi_update"
+ [(set (match_operator:QI 4 "store_update_operand"
+ [(match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "short_immediate_operand" "I")])
+ (match_operand:QI 3 "register_operand" "r"))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "stb.a%V4 %3,[%0,%2]"
+ [(set_attr "type" "store")
+ (set_attr "length" "1")])
+
+(define_insn "*loadhi_update"
+ [(set (match_operand:HI 3 "register_operand" "=r,r")
+ (match_operator:HI 4 "load_update_operand"
+ [(match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
+ (set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "ldw.a%V4 %3,[%0,%2]"
+ [(set_attr "type" "load,load")
+ (set_attr "length" "1,2")])
+
+(define_insn "*load_zeroextendhisi_update"
+ [(set (match_operand:SI 3 "register_operand" "=r,r")
+ (zero_extend:SI (match_operator:HI 4 "load_update_operand"
+ [(match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
+ (set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "ldw.a%V4 %3,[%0,%2]"
+ [(set_attr "type" "load,load")
+ (set_attr "length" "1,2")])
+
+(define_insn "*load_signextendhisi_update"
+ [(set (match_operand:SI 3 "register_operand" "=r,r")
+ (sign_extend:SI (match_operator:HI 4 "load_update_operand"
+ [(match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
+ (set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "ldw.x.a%V4 %3,[%0,%2]"
+ [(set_attr "type" "load,load")
+ (set_attr "length" "1,2")])
+
+(define_insn "*storehi_update"
+ [(set (match_operator:HI 4 "store_update_operand"
+ [(match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "short_immediate_operand" "I")])
+ (match_operand:HI 3 "register_operand" "r"))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "stw.a%V4 %3,[%0,%2]"
+ [(set_attr "type" "store")
+ (set_attr "length" "1")])
+
+(define_insn "*loadsi_update"
+ [(set (match_operand:SI 3 "register_operand" "=r,r")
+ (match_operator:SI 4 "load_update_operand"
+ [(match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
+ (set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "ld.a%V4 %3,[%0,%2]"
+ [(set_attr "type" "load,load")
+ (set_attr "length" "1,2")])
+
+(define_insn "*storesi_update"
+ [(set (match_operator:SI 4 "store_update_operand"
+ [(match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "short_immediate_operand" "I")])
+ (match_operand:SI 3 "register_operand" "r"))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "st.a%V4 %3,[%0,%2]"
+ [(set_attr "type" "store")
+ (set_attr "length" "1")])
+
+(define_insn "*loadsf_update"
+ [(set (match_operand:SF 3 "register_operand" "=r,r")
+ (match_operator:SF 4 "load_update_operand"
+ [(match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
+ (set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "ld.a%V4 %3,[%0,%2]"
+ [(set_attr "type" "load,load")
+ (set_attr "length" "1,2")])
+
+(define_insn "*storesf_update"
+ [(set (match_operator:SF 4 "store_update_operand"
+ [(match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "short_immediate_operand" "I")])
+ (match_operand:SF 3 "register_operand" "r"))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "st.a%V4 %3,[%0,%2]"
+ [(set_attr "type" "store")
+ (set_attr "length" "1")])
+
+;; Conditional move instructions.
+
+(define_expand "movsicc"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (if_then_else (match_operand 1 "comparison_operator" "")
+ (match_operand:SI 2 "nonmemory_operand" "")
+ (match_operand:SI 3 "register_operand" "")))]
+ ""
+ "
+{
+ enum rtx_code code = GET_CODE (operands[1]);
+ rtx ccreg = gen_rtx (REG,
+ SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
+ 61);
+
+ operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
+}")
+
+;(define_expand "movdicc"
+; [(set (match_operand:DI 0 "register_operand" "")
+; (if_then_else (match_operand 1 "comparison_operator" "")
+; (match_operand:DI 2 "nonmemory_operand" "")
+; (match_operand:DI 3 "register_operand" "")))]
+; "0 /* ??? this would work better if we had cmpdi */"
+; "
+;{
+; enum rtx_code code = GET_CODE (operands[1]);
+; rtx ccreg = gen_rtx (REG,
+; SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
+; 61);
+;
+; operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
+;}")
+
+(define_expand "movsfcc"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (if_then_else (match_operand 1 "comparison_operator" "")
+ (match_operand:SF 2 "nonmemory_operand" "")
+ (match_operand:SF 3 "register_operand" "")))]
+ ""
+ "
+{
+ enum rtx_code code = GET_CODE (operands[1]);
+ rtx ccreg = gen_rtx (REG,
+ SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
+ 61);
+
+ operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
+}")
+
+;(define_expand "movdfcc"
+; [(set (match_operand:DF 0 "register_operand" "")
+; (if_then_else (match_operand 1 "comparison_operator" "")
+; (match_operand:DF 2 "nonmemory_operand" "")
+; (match_operand:DF 3 "register_operand" "")))]
+; "0 /* ??? can generate less efficient code if constants involved */"
+; "
+;{
+; enum rtx_code code = GET_CODE (operands[1]);
+; rtx ccreg = gen_rtx (REG,
+; SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
+; 61);
+;
+; operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
+;}")
+
+(define_insn "*movsicc_insn"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (if_then_else (match_operand 1 "comparison_operator" "")
+ (match_operand:SI 2 "nonmemory_operand" "rJi")
+ (match_operand:SI 3 "register_operand" "0")))]
+ ""
+ "mov.%d1 %0,%S2"
+ [(set_attr "type" "cmove")])
+
+; ??? This doesn't properly handle constants.
+;(define_insn "*movdicc_insn"
+; [(set (match_operand:DI 0 "register_operand" "=r,r")
+; (if_then_else (match_operand 1 "comparison_operator" "")
+; (match_operand:DI 2 "nonmemory_operand" "r,Ji")
+; (match_operand:DI 3 "register_operand" "0,0")))]
+; "0"
+; "*
+;{
+; switch (which_alternative)
+; {
+; case 0 :
+; /* We normally copy the low-numbered register first. However, if
+; the first register operand 0 is the same as the second register of
+; operand 1, we must copy in the opposite order. */
+; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
+; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
+; else
+; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
+; case 1 :
+; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
+; }
+;}"
+; [(set_attr "type" "cmove,cmove")
+; (set_attr "length" "2,4")])
+
+(define_insn "*movsfcc_insn"
+ [(set (match_operand:SF 0 "register_operand" "=r,r")
+ (if_then_else (match_operand 1 "comparison_operator" "")
+ (match_operand:SF 2 "nonmemory_operand" "r,E")
+ (match_operand:SF 3 "register_operand" "0,0")))]
+ ""
+ "@
+ mov.%d1 %0,%2
+ mov.%d1 %0,%2 ; %A2"
+ [(set_attr "type" "cmove,cmove")])
+
+;(define_insn "*movdfcc_insn"
+; [(set (match_operand:DF 0 "register_operand" "=r,r")
+; (if_then_else (match_operand 1 "comparison_operator" "")
+; (match_operand:DF 2 "nonmemory_operand" "r,E")
+; (match_operand:DF 3 "register_operand" "0,0")))]
+; "0"
+; "*
+;{
+; switch (which_alternative)
+; {
+; case 0 :
+; /* We normally copy the low-numbered register first. However, if
+; the first register operand 0 is the same as the second register of
+; operand 1, we must copy in the opposite order. */
+; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
+; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
+; else
+; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
+; case 1 :
+; return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\";
+; }
+;}"
+; [(set_attr "type" "cmove,cmove")
+; (set_attr "length" "2,4")])
+
+;; Zero extension instructions.
+;; ??? We don't support volatile memrefs here, but I'm not sure why.
+
+(define_insn "zero_extendqihi2"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
+ ""
+ "@
+ extb%? %0,%1
+ ldb%U1 %0,%1"
+ [(set_attr "type" "unary,load")])
+
+(define_insn "*zero_extendqihi2_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CCZN
+ (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:HI 0 "register_operand" "=r")
+ (zero_extend:HI (match_dup 1)))]
+ ""
+ "extb%?.f %0,%1"
+ [(set_attr "type" "unary")
+ (set_attr "cond" "set_zn")])
+
+(define_insn "zero_extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
+ ""
+ "@
+ extb%? %0,%1
+ ldb%U1 %0,%1"
+ [(set_attr "type" "unary,load")])
+
+(define_insn "*zero_extendqisi2_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CCZN
+ (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (match_dup 1)))]
+ ""
+ "extb%?.f %0,%1"
+ [(set_attr "type" "unary")
+ (set_attr "cond" "set_zn")])
+
+(define_insn "zero_extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
+ ""
+ "@
+ extw%? %0,%1
+ ldw%U1 %0,%1"
+ [(set_attr "type" "unary,load")])
+
+(define_insn "*zero_extendhisi2_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CCZN
+ (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (match_dup 1)))]
+ ""
+ "extw%?.f %0,%1"
+ [(set_attr "type" "unary")
+ (set_attr "cond" "set_zn")])
+
+;; Sign extension instructions.
+
+(define_insn "extendqihi2"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
+ ""
+ "@
+ sexb%? %0,%1
+ ldb.x%U1 %0,%1"
+ [(set_attr "type" "unary,load")])
+
+(define_insn "*extendqihi2_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CCZN
+ (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:HI 0 "register_operand" "=r")
+ (sign_extend:HI (match_dup 1)))]
+ ""
+ "sexb%?.f %0,%1"
+ [(set_attr "type" "unary")
+ (set_attr "cond" "set_zn")])
+
+(define_insn "extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
+ ""
+ "@
+ sexb%? %0,%1
+ ldb.x%U1 %0,%1"
+ [(set_attr "type" "unary,load")])
+
+(define_insn "*extendqisi2_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CCZN
+ (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (match_dup 1)))]
+ ""
+ "sexb%?.f %0,%1"
+ [(set_attr "type" "unary")
+ (set_attr "cond" "set_zn")])
+
+(define_insn "extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
+ ""
+ "@
+ sexw%? %0,%1
+ ldw.x%U1 %0,%1"
+ [(set_attr "type" "unary,load")])
+
+(define_insn "*extendhisi2_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CCZN
+ (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (match_dup 1)))]
+ ""
+ "sexw%?.f %0,%1"
+ [(set_attr "type" "unary")
+ (set_attr "cond" "set_zn")])
+
+;; Arithmetic instructions.
+
+(define_insn "addsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_operand:SI 1 "register_operand" "%r")
+ (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
+ ""
+ "add%? %0,%1,%2")
+
+(define_insn "*addsi3_set_cc_insn"
+ [(set (reg:CC 61) (compare:CC
+ (plus:SI (match_operand:SI 1 "register_operand" "%r")
+ (match_operand:SI 2 "nonmemory_operand" "rIJ"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_dup 1)
+ (match_dup 2)))]
+ ""
+ "add%?.f %0,%1,%2"
+ [(set_attr "cond" "set")])
+
+(define_insn "adddi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "nonmemory_operand" "%r")
+ (match_operand:DI 2 "nonmemory_operand" "ri")))
+ (clobber (reg:CC 61))]
+ ""
+ "*
+{
+ rtx op2 = operands[2];
+
+ if (GET_CODE (op2) == CONST_INT)
+ {
+ int sign = INTVAL (op2);
+ if (sign < 0)
+ return \"add.f %L0,%L1,%2\;adc %H0,%H1,-1\";
+ else
+ return \"add.f %L0,%L1,%2\;adc %H0,%H1,0\";
+ }
+ else
+ return \"add.f %L0,%L1,%L2\;adc %H0,%H1,%H2\";
+}"
+ [(set_attr "length" "2")])
+
+(define_insn "subsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (minus:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
+ ""
+ "sub%? %0,%1,%2")
+
+(define_insn "*subsi3_set_cc_insn"
+ [(set (reg:CC 61) (compare:CC
+ (minus:SI (match_operand:SI 1 "register_operand" "%r")
+ (match_operand:SI 2 "nonmemory_operand" "rIJ"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (minus:SI (match_dup 1)
+ (match_dup 2)))]
+ ""
+ "sub%?.f %0,%1,%2"
+ [(set_attr "cond" "set")])
+
+(define_insn "subdi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (minus:DI (match_operand:DI 1 "nonmemory_operand" "r")
+ (match_operand:DI 2 "nonmemory_operand" "ri")))
+ (clobber (reg:CC 61))]
+ ""
+ "*
+{
+ rtx op2 = operands[2];
+
+ if (GET_CODE (op2) == CONST_INT)
+ {
+ int sign = INTVAL (op2);
+ if (sign < 0)
+ return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,-1\";
+ else
+ return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,0\";
+ }
+ else
+ return \"sub.f %L0,%L1,%L2\;sbc %H0,%H1,%H2\";
+}"
+ [(set_attr "length" "2")])
+
+;; Boolean instructions.
+;;
+;; We don't define the DImode versions as expand_binop does a good enough job.
+
+(define_insn "andsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (match_operand:SI 1 "register_operand" "%r")
+ (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
+ ""
+ "and%? %0,%1,%2")
+
+(define_insn "*andsi3_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CCZN
+ (and:SI (match_operand:SI 1 "register_operand" "%r")
+ (match_operand:SI 2 "nonmemory_operand" "rIJ"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (match_dup 1)
+ (match_dup 2)))]
+ ""
+ "and%?.f %0,%1,%2"
+ [(set_attr "cond" "set_zn")])
+
+(define_insn "*bicsi3_insn"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
+ (and:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
+ (not:SI (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r"))))]
+ ""
+ "bic%? %0,%1,%2"
+ [(set_attr "length" "1,2,1,2")])
+
+(define_insn "*bicsi3_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CCZN
+ (and:SI (match_operand:SI 1 "register_operand" "%r")
+ (not:SI (match_operand:SI 2 "nonmemory_operand" "rIJ")))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (match_dup 1)
+ (not:SI (match_dup 2))))]
+ ""
+ "bic%?.f %0,%1,%2"
+ [(set_attr "cond" "set_zn")])
+
+(define_insn "iorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (match_operand:SI 1 "register_operand" "%r")
+ (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
+ ""
+ "or%? %0,%1,%2")
+
+(define_insn "*iorsi3_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CCZN
+ (ior:SI (match_operand:SI 1 "register_operand" "%r")
+ (match_operand:SI 2 "nonmemory_operand" "rIJ"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (match_dup 1)
+ (match_dup 2)))]
+ ""
+ "or%?.f %0,%1,%2"
+ [(set_attr "cond" "set_zn")])
+
+(define_insn "xorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (xor:SI (match_operand:SI 1 "register_operand" "%r")
+ (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
+ ""
+ "xor%? %0,%1,%2")
+
+(define_insn "*xorsi3_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CCZN
+ (xor:SI (match_operand:SI 1 "register_operand" "%r")
+ (match_operand:SI 2 "nonmemory_operand" "rIJ"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (xor:SI (match_dup 1)
+ (match_dup 2)))]
+ ""
+ "xor%?.f %0,%1,%2"
+ [(set_attr "cond" "set_zn")])
+
+(define_insn "negsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (neg:SI (match_operand:SI 1 "register_operand" "r")))]
+ ""
+ "sub%? %0,0,%1"
+ [(set_attr "type" "unary")])
+
+(define_insn "*negsi2_set_cc_insn"
+ [(set (reg:CC 61) (compare:CC
+ (neg:SI (match_operand:SI 1 "register_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (neg:SI (match_dup 1)))]
+ ""
+ "sub%?.f %0,0,%1"
+ [(set_attr "type" "unary")
+ (set_attr "cond" "set")])
+
+(define_insn "negdi2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (neg:DI (match_operand:DI 1 "register_operand" "r")))
+ (clobber (reg:SI 61))]
+ ""
+ "sub.f %L0,0,%L1\;sbc %H0,0,%H1"
+ [(set_attr "type" "unary")
+ (set_attr "length" "2")])
+
+(define_insn "one_cmplsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (not:SI (match_operand:SI 1 "register_operand" "r")))]
+ ""
+ "xor%? %0,%1,-1"
+ [(set_attr "type" "unary")])
+
+(define_insn "*one_cmplsi2_set_cc_insn"
+ [(set (reg:CCZN 61) (compare:CC
+ (not:SI (match_operand:SI 1 "register_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (not:SI (match_dup 1)))]
+ ""
+ "xor%?.f %0,%1,-1"
+ [(set_attr "type" "unary")
+ (set_attr "cond" "set_zn")])
+
+;; Shift instructions.
+
+(define_expand "ashlsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (ashift:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))]
+ ""
+ "
+{
+ if (! TARGET_SHIFTER)
+ {
+ emit_insn (gen_rtx
+ (PARALLEL, VOIDmode,
+ gen_rtvec (2,
+ gen_rtx (SET, VOIDmode, operands[0],
+ gen_rtx (ASHIFT, SImode, operands[1], operands[2])),
+ gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))));
+ DONE;
+ }
+}")
+
+(define_expand "ashrsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))]
+ ""
+ "
+{
+ if (! TARGET_SHIFTER)
+ {
+ emit_insn (gen_rtx
+ (PARALLEL, VOIDmode,
+ gen_rtvec (2,
+ gen_rtx (SET, VOIDmode, operands[0],
+ gen_rtx (ASHIFTRT, SImode, operands[1], operands[2])),
+ gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))));
+ DONE;
+ }
+}")
+
+(define_expand "lshrsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))]
+ ""
+ "
+{
+ if (! TARGET_SHIFTER)
+ {
+ emit_insn (gen_rtx
+ (PARALLEL, VOIDmode,
+ gen_rtvec (2,
+ gen_rtx (SET, VOIDmode, operands[0],
+ gen_rtx (LSHIFTRT, SImode, operands[1], operands[2])),
+ gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))));
+ DONE;
+ }
+}")
+
+(define_insn "*ashlsi3_insn"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
+ (ashift:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
+ (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
+ "TARGET_SHIFTER"
+ "asl%? %0,%1,%2"
+ [(set_attr "type" "shift")
+ (set_attr "length" "1,2,1,2")])
+
+(define_insn "*ashrsi3_insn"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
+ (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
+ (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
+ "TARGET_SHIFTER"
+ "asr%? %0,%1,%2"
+ [(set_attr "type" "shift")
+ (set_attr "length" "1,2,1,2")])
+
+(define_insn "*lshrsi3_insn"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
+ (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
+ (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
+ "TARGET_SHIFTER"
+ "lsr%? %0,%1,%2"
+ [(set_attr "type" "shift")
+ (set_attr "length" "1,2,1,2")])
+
+(define_insn "*shift_si3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operator:SI 3 "shift_operator"
+ [(match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "nonmemory_operand" "rIJ")]))
+ (clobber (match_scratch:SI 4 "=&r"))]
+ "! TARGET_SHIFTER"
+ "* return output_shift (operands);"
+ [(set_attr "type" "shift")
+ (set_attr "length" "8")])
+
+;; Compare instructions.
+;; This controls RTL generation and register allocation.
+
+;; We generate RTL for comparisons and branches by having the cmpxx
+;; patterns store away the operands. Then, the scc and bcc patterns
+;; emit RTL for both the compare and the branch.
+
+(define_expand "cmpsi"
+ [(set (reg:CC 61)
+ (compare:CC (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "nonmemory_operand" "")))]
+ ""
+ "
+{
+ arc_compare_op0 = operands[0];
+ arc_compare_op1 = operands[1];
+ DONE;
+}")
+
+;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
+;; This assumes sub.f 0,symbol,0 is a valid insn.
+;; Note that "sub.f 0,r0,1" is an 8 byte insn. To avoid unnecessarily
+;; creating 8 byte insns we duplicate %1 in the destination reg of the insn
+;; if it's a small constant.
+
+(define_insn "*cmpsi_cc_insn"
+ [(set (reg:CC 61)
+ (compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
+ (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
+ ""
+ "@
+ sub.f 0,%0,%1
+ sub.f %1,%0,%1
+ sub.f 0,%0,%1"
+ [(set_attr "type" "compare,compare,compare")])
+
+(define_insn "*cmpsi_cczn_insn"
+ [(set (reg:CCZN 61)
+ (compare:CCZN (match_operand:SI 0 "register_operand" "r,r,r")
+ (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
+ ""
+ "@
+ sub.f 0,%0,%1
+ sub.f %1,%0,%1
+ sub.f 0,%0,%1"
+ [(set_attr "type" "compare,compare,compare")])
+
+(define_insn "*cmpsi_ccznc_insn"
+ [(set (reg:CCZNC 61)
+ (compare:CCZNC (match_operand:SI 0 "register_operand" "r,r,r")
+ (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
+ ""
+ "@
+ sub.f 0,%0,%1
+ sub.f %1,%0,%1
+ sub.f 0,%0,%1"
+ [(set_attr "type" "compare,compare,compare")])
+
+;; Next come the scc insns.
+
+(define_expand "seq"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (eq:SI (match_dup 1) (const_int 0)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "sne"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ne:SI (match_dup 1) (const_int 0)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "sgt"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (gt:SI (match_dup 1) (const_int 0)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "sle"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (le:SI (match_dup 1) (const_int 0)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "sge"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ge:SI (match_dup 1) (const_int 0)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "slt"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lt:SI (match_dup 1) (const_int 0)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "sgtu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (gtu:SI (match_dup 1) (const_int 0)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "sleu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (leu:SI (match_dup 1) (const_int 0)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "sgeu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (geu:SI (match_dup 1) (const_int 0)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "sltu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ltu:SI (match_dup 1) (const_int 0)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_insn "*scc_insn"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operator:SI 1 "comparison_operator" [(reg 61) (const_int 0)]))]
+ ""
+ "mov %0,1\;sub.%D1 %0,%0,%0"
+ [(set_attr "type" "unary")
+ (set_attr "length" "2")])
+
+;; ??? Look up negscc insn. See pa.md for example.
+(define_insn "*neg_scc_insn"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (neg:SI (match_operator:SI 1 "comparison_operator"
+ [(reg 61) (const_int 0)])))]
+ ""
+ "mov %0,-1\;sub.%D1 %0,%0,%0"
+ [(set_attr "type" "unary")
+ (set_attr "length" "2")])
+
+(define_insn "*not_scc_insn"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (not:SI (match_operator:SI 1 "comparison_operator"
+ [(reg 61) (const_int 0)])))]
+ ""
+ "mov %0,1\;sub.%d1 %0,%0,%0"
+ [(set_attr "type" "unary")
+ (set_attr "length" "2")])
+
+;; These control RTL generation for conditional jump insns
+
+(define_expand "beq"
+ [(set (pc)
+ (if_then_else (eq (match_dup 1) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "bne"
+ [(set (pc)
+ (if_then_else (ne (match_dup 1) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "bgt"
+ [(set (pc)
+ (if_then_else (gt (match_dup 1) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "ble"
+ [(set (pc)
+ (if_then_else (le (match_dup 1) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "bge"
+ [(set (pc)
+ (if_then_else (ge (match_dup 1) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "blt"
+ [(set (pc)
+ (if_then_else (lt (match_dup 1) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "bgtu"
+ [(set (pc)
+ (if_then_else (gtu (match_dup 1) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "bleu"
+ [(set (pc)
+ (if_then_else (leu (match_dup 1) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "bgeu"
+ [(set (pc)
+ (if_then_else (geu (match_dup 1) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
+}")
+
+(define_expand "bltu"
+ [(set (pc)
+ (if_then_else (ltu (match_dup 1) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
+}")
+
+;; Now match both normal and inverted jump.
+
+(define_insn "*branch_insn"
+ [(set (pc)
+ (if_then_else (match_operator 1 "proper_comparison_operator"
+ [(reg 61) (const_int 0)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ if (arc_ccfsm_branch_deleted_p ())
+ {
+ arc_ccfsm_record_branch_deleted ();
+ return \"; branch deleted, next insns conditionalized\";
+ }
+ else
+ return \"%~b%d1%# %l0\";
+}"
+ [(set_attr "type" "branch")])
+
+(define_insn "*rev_branch_insn"
+ [(set (pc)
+ (if_then_else (match_operator 1 "proper_comparison_operator"
+ [(reg 61) (const_int 0)])
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
+ "*
+{
+ if (arc_ccfsm_branch_deleted_p ())
+ {
+ arc_ccfsm_record_branch_deleted ();
+ return \"; branch deleted, next insns conditionalized\";
+ }
+ else
+ return \"%~b%D1%# %l0\";
+}"
+ [(set_attr "type" "branch")])
+
+;; Unconditional and other jump instructions.
+
+(define_insn "jump"
+ [(set (pc) (label_ref (match_operand 0 "" "")))]
+ ""
+ "b%* %l0"
+ [(set_attr "type" "uncond_branch")])
+
+(define_insn "indirect_jump"
+ [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
+ ""
+ "j%* %a0"
+ [(set_attr "type" "uncond_branch")])
+
+;; Implement a switch statement.
+;; This wouldn't be necessary in the non-pic case if we could distinguish
+;; label refs of the jump table from other label refs. The problem is that
+;; label refs are output as "%st(.LL42)" but we don't want the %st - we want
+;; the real address since it's the address of the table.
+
+(define_expand "casesi"
+ [(set (match_dup 5)
+ (minus:SI (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "nonmemory_operand" "")))
+ (set (reg:CC 61)
+ (compare:CC (match_dup 5)
+ (match_operand:SI 2 "nonmemory_operand" "")))
+ (set (pc)
+ (if_then_else (gtu (reg:CC 61)
+ (const_int 0))
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (parallel
+ [(set (pc)
+ (mem:SI (plus:SI (mult:SI (match_dup 5)
+ (const_int 4))
+ (label_ref (match_operand 3 "" "")))))
+ (clobber (match_scratch:SI 6 ""))
+ (clobber (match_scratch:SI 7 ""))])]
+ ""
+ "
+{
+ operands[5] = gen_reg_rtx (SImode);
+}")
+
+(define_insn "*casesi_insn"
+ [(set (pc)
+ (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"))
+ (clobber (match_scratch:SI 3 "=r"))]
+ ""
+ "*
+{
+ output_asm_insn (\"mov %2,%1\", operands);
+ if (TARGET_SHIFTER)
+ output_asm_insn (\"asl %3,%0,2\", operands);
+ else
+ output_asm_insn (\"asl %3,%0\;asl %3,%3\", operands);
+ output_asm_insn (\"ld %2,[%2,%3]\", operands);
+ output_asm_insn (\"j.nd %a2\", operands);
+ return \"\";
+}"
+ [(set_attr "type" "uncond_branch")
+ (set_attr "length" "6")])
+
+(define_insn "tablejump"
+ [(set (pc) (match_operand:SI 0 "address_operand" "p"))
+ (use (label_ref (match_operand 1 "" "")))]
+ "0 /* disabled -> using casesi now */"
+ "j%* %a0"
+ [(set_attr "type" "uncond_branch")])
+
+(define_expand "call"
+ ;; operands[1] is stack_size_rtx
+ ;; operands[2] is next_arg_register
+ [(parallel [(call (match_operand:SI 0 "call_operand" "")
+ (match_operand 1 "" ""))
+ (clobber (reg:SI 31))])]
+ ""
+ "")
+
+(define_insn "*call_via_reg"
+ [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
+ (match_operand 1 "" ""))
+ (clobber (reg:SI 31))]
+ ""
+ "lr blink,[status]\;j.d %0\;add blink,blink,2"
+ [(set_attr "type" "call_no_delay_slot")
+ (set_attr "length" "3")])
+
+(define_insn "*call_via_label"
+ [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
+ (match_operand 1 "" ""))
+ (clobber (reg:SI 31))]
+ ""
+ ; The %~ is necessary in case this insn gets conditionalized and the previous
+ ; insn is the cc setter.
+ "%~bl%!%* %0"
+ [(set_attr "type" "call")
+ (set_attr "cond" "canuse")])
+
+(define_expand "call_value"
+ ;; operand 2 is stack_size_rtx
+ ;; operand 3 is next_arg_register
+ [(parallel [(set (match_operand 0 "register_operand" "=r")
+ (call (match_operand:SI 1 "call_operand" "")
+ (match_operand 2 "" "")))
+ (clobber (reg:SI 31))])]
+ ""
+ "")
+
+(define_insn "*call_value_via_reg"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand 2 "" "")))
+ (clobber (reg:SI 31))]
+ ""
+ "lr blink,[status]\;j.d %1\;add blink,blink,2"
+ [(set_attr "type" "call_no_delay_slot")
+ (set_attr "length" "3")])
+
+(define_insn "*call_value_via_label"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
+ (match_operand 2 "" "")))
+ (clobber (reg:SI 31))]
+ ""
+ ; The %~ is necessary in case this insn gets conditionalized and the previous
+ ; insn is the cc setter.
+ "%~bl%!%* %1"
+ [(set_attr "type" "call")
+ (set_attr "cond" "canuse")])
+
+(define_insn "nop"
+ [(const_int 0)]
+ ""
+ "nop"
+ [(set_attr "type" "misc")])
+
+;; Special pattern to flush the icache.
+;; ??? Not sure what to do here. Some ARC's are known to support this.
+
+(define_insn "flush_icache"
+ [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
+ ""
+ "* return \"\";"
+ [(set_attr "type" "misc")])
+
+;; Split up troublesome insns for better scheduling.
+
+;; Peepholes go at the end.
diff --git a/gnu/usr.bin/gcc/config/arc/initfini.c b/gnu/usr.bin/gcc/config/arc/initfini.c
new file mode 100644
index 00000000000..084e2292bf5
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arc/initfini.c
@@ -0,0 +1,157 @@
+/* .init/.fini section handling + C++ global constructor/destructor handling.
+ This file is based on crtstuff.c, sol2-crti.asm, sol2-crtn.asm.
+
+Copyright (C) 1995, 1997 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. */
+
+/* As a special exception, if you link this file 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. */
+
+/* Declare a pointer to void function type. */
+typedef void (*func_ptr) (void);
+
+#ifdef CRT_INIT
+
+/* NOTE: In order to be able to support SVR4 shared libraries, we arrange
+ to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
+ __DTOR_END__ } per root executable and also one set of these symbols
+ per shared library. So in any given whole process image, we may have
+ multiple definitions of each of these symbols. In order to prevent
+ these definitions from conflicting with one another, and in order to
+ ensure that the proper lists are used for the initialization/finalization
+ of each individual shared library (respectively), we give these symbols
+ only internal (i.e. `static') linkage, and we also make it a point to
+ refer to only the __CTOR_END__ symbol in crtfini.o and the __DTOR_LIST__
+ symbol in crtinit.o, where they are defined. */
+
+static func_ptr __CTOR_LIST__[1] __attribute__ ((section (".ctors")))
+ = { (func_ptr) (-1) };
+
+static func_ptr __DTOR_LIST__[1] __attribute__ ((section (".dtors")))
+ = { (func_ptr) (-1) };
+
+/* Run all the global destructors on exit from the program. */
+
+/* Some systems place the number of pointers in the first word of the
+ table. On SVR4 however, that word is -1. In all cases, the table is
+ null-terminated. On SVR4, we start from the beginning of the list and
+ invoke each per-compilation-unit destructor routine in order
+ until we find that null.
+
+ Note that this function MUST be static. There will be one of these
+ functions in each root executable and one in each shared library, but
+ although they all have the same code, each one is unique in that it
+ refers to one particular associated `__DTOR_LIST__' which belongs to the
+ same particular root executable or shared library file. */
+
+static void __do_global_dtors ()
+asm ("__do_global_dtors") __attribute__ ((section (".text")));
+
+static void
+__do_global_dtors ()
+{
+ func_ptr *p;
+ for (p = __DTOR_LIST__ + 1; *p; p++)
+ (*p) ();
+}
+
+/* .init section start.
+ This must appear at the start of the .init section. */
+
+asm ("
+ .section .init\n
+ .global init\n
+ .word 0\n
+init:\n
+ st blink,[sp,4]\n
+ st fp,[sp]\n
+ mov fp,sp\n
+ sub sp,sp,16\n
+");
+
+/* .fini section start.
+ This must appear at the start of the .init section. */
+
+asm ("
+ .section .fini\n
+ .global fini\n
+ .word 0\n
+fini:\n
+ st blink,[sp,4]\n
+ st fp,[sp]\n
+ mov fp,sp\n
+ sub sp,sp,16\n
+ bl.nd __do_global_dtors
+");
+
+#endif /* CRT_INIT */
+
+#ifdef CRT_FINI
+
+/* Put a word containing zero at the end of each of our two lists of function
+ addresses. Note that the words defined here go into the .ctors and .dtors
+ sections of the crtend.o file, and since that file is always linked in
+ last, these words naturally end up at the very ends of the two lists
+ contained in these two sections. */
+
+static func_ptr __CTOR_END__[1] __attribute__ ((section (".ctors")))
+ = { (func_ptr) 0 };
+
+static func_ptr __DTOR_END__[1] __attribute__ ((section (".dtors")))
+ = { (func_ptr) 0 };
+
+/* Run all global constructors for the program.
+ Note that they are run in reverse order. */
+
+static void __do_global_ctors ()
+asm ("__do_global_ctors") __attribute__ ((section (".text")));
+
+static void
+__do_global_ctors ()
+{
+ func_ptr *p;
+ for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
+ (*p) ();
+}
+
+/* .init section end.
+ This must live at the end of the .init section. */
+
+asm ("
+ .section .init\n
+ bl.nd __do_global_ctors
+ ld blink,[fp,4]\n
+ j.d blink\n
+ ld.a fp,[sp,16]\n
+");
+
+/* .fini section end.
+ This must live at the end of the .fini section. */
+
+asm ("
+ .section .fini\n
+ ld blink,[fp,4]\n
+ j.d blink\n
+ ld.a fp,[sp,16]\n
+");
+
+#endif /* CRT_FINI */
diff --git a/gnu/usr.bin/gcc/config/arc/lib1funcs.asm b/gnu/usr.bin/gcc/config/arc/lib1funcs.asm
new file mode 100644
index 00000000000..a2d509ac765
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arc/lib1funcs.asm
@@ -0,0 +1,273 @@
+; libgcc1 routines for ARC cpu.
+
+/* Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+
+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 GNU CC; 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 other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself 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. */
+
+#ifdef L_mulsi3
+ .section .text
+ .align 4
+
+#ifdef __base__
+ .cpu base
+ .global ___mulsi3
+___mulsi3:
+
+/* This the simple version.
+
+ while (a)
+ {
+ if (a & 1)
+ r += b;
+ a >>= 1;
+ b <<= 1;
+ }
+*/
+ mov r2,0 ; Accumulate result here.
+.Lloop:
+ sub.f 0,r0,0 ; while (a)
+ nop
+ beq.nd .Ldone
+ and.f 0,r0,1 ; if (a & 1)
+ add.nz r2,r2,r1 ; r += b
+ lsr r0,r0 ; a >>= 1
+ b.d .Lloop
+ lsl r1,r1 ; b <<= 1
+.Ldone:
+ j.d blink
+ mov r0,r2
+#endif
+
+#endif /* L_mulsi3 */
+
+#ifdef L_umulsidi3
+ .section .text
+ .align 4
+
+#ifdef __base__
+ .cpu base
+ .global ___umulsidi3
+___umulsidi3:
+
+/* This the simple version.
+
+ while (a)
+ {
+ if (a & 1)
+ r += b;
+ a >>= 1;
+ b <<= 1;
+ }
+*/
+ mov r2,0 ; Top part of b.
+ mov r3,0 ; Accumulate result here.
+ mov r4,0
+.Lloop:
+ sub.f 0,r0,0 ; while (a)
+ nop
+ beq.nd .Ldone
+ and.f 0,r0,1 ; if (a & 1)
+ add.nz r4,r4,r1 ; r += b
+ adc.nz r3,r3,r2
+ lsr r0,r0 ; a >>= 1
+ lsl.f r1,r1 ; b <<= 1
+ b.d .Lloop
+ rlc r2,r2
+.Ldone:
+#ifdef __big_endian__
+ mov r1,r4
+ j.d blink
+ mov r0,r3
+#else
+ mov r0,r4
+ j.d blink
+ mov r1,r3
+#endif
+#endif
+
+#endif /* L_umulsidi3 */
+
+#ifdef L_divmod_tools
+
+; Utilities used by all routines.
+
+ .section .text
+ .align 4
+
+; inputs: r0 = numerator, r1 = denominator
+; outputs: positive r0/r1,
+; r6.bit1 = sign of numerator, r6.bit0 = sign of result
+
+ .global ___divnorm
+___divnorm:
+ mov r6,0 ; keep sign in r6
+ sub.f 0,r0,0 ; is numerator -ve?
+ sub.lt r0,0,r0 ; negate numerator
+ mov.lt r6,3 ; sign is -ve
+ sub.f 0,r1,0 ; is denominator -ve?
+ sub.lt r1,0,r1 ; negate denominator
+ xor.lt r6,r6,1 ; toggle sign
+ j.nd blink
+
+/*
+unsigned long
+udivmodsi4(int modwanted, unsigned long num, unsigned long den)
+{
+ unsigned long bit = 1;
+ unsigned long res = 0;
+
+ while (den < num && bit && !(den & (1L<<31)))
+ {
+ den <<=1;
+ bit <<=1;
+ }
+ while (bit)
+ {
+ if (num >= den)
+ {
+ num -= den;
+ res |= bit;
+ }
+ bit >>=1;
+ den >>=1;
+ }
+ if (modwanted) return num;
+ return res;
+}
+*/
+
+; inputs: r0 = numerator, r1 = denominator
+; outputs: r0 = quotient, r1 = remainder, r2/r3 trashed
+
+ .global ___udivmodsi4
+___udivmodsi4:
+ mov r2,1 ; bit = 1
+ mov r3,0 ; res = 0
+.Lloop1:
+ sub.f 0,r1,r0 ; while (den < num
+ nop
+ bnc.nd .Lloop2
+ sub.f 0,r2,0 ; && bit
+ nop
+ bz.nd .Lloop2
+ lsl.f 0,r1 ; && !(den & (1<<31))
+ nop
+ bc.nd .Lloop2
+ lsl r1,r1 ; den <<= 1
+ b.d .Lloop1
+ lsl r2,r2 ; bit <<= 1
+.Lloop2:
+ sub.f 0,r2,0 ; while (bit)
+ nop
+ bz.nd .Ldivmodend
+ sub.f 0,r0,r1 ; if (num >= den)
+ nop
+ bc.nd .Lshiftdown
+ sub r0,r0,r1 ; num -= den
+ or r3,r3,r2 ; res |= bit
+.Lshiftdown:
+ lsr r2,r2 ; bit >>= 1
+ b.d .Lloop2
+ lsr r1,r1 ; den >>= 1
+.Ldivmodend:
+ mov r1,r0 ; r1 = mod
+ j.d blink
+ mov r0,r3 ; r0 = res
+
+#endif
+
+#ifdef L_udivsi3
+ .section .text
+ .align 4
+
+#ifdef __base__
+ .cpu base
+ .global ___udivsi3
+___udivsi3:
+ mov r7,blink
+ bl.nd ___udivmodsi4
+ j.nd r7
+#endif
+
+#endif /* L_udivsi3 */
+
+#ifdef L_divsi3
+ .section .text
+ .align 4
+
+#ifdef __base__
+ .cpu base
+ .global ___divsi3
+___divsi3:
+ mov r7,blink
+ bl.nd ___divnorm
+ bl.nd ___udivmodsi4
+ and.f 0,r6,1
+ sub.nz r0,0,r0 ; cannot go in delay slot, has limm value
+ j.nd r7
+#endif
+
+#endif /* L_divsi3 */
+
+#ifdef L_umodsi3
+ .section .text
+ .align 4
+
+#ifdef __base__
+ .cpu base
+ .global ___umodsi3
+___umodsi3:
+ mov r7,blink
+ bl.nd ___udivmodsi4
+ j.d r7
+ mov r0,r1
+#endif
+
+#endif /* L_umodsi3 */
+
+#ifdef L_modsi3
+ .section .text
+ .align 4
+
+#ifdef __base__
+ .cpu base
+ .global ___modsi3
+___modsi3:
+ mov r7,blink
+ bl.nd ___divnorm
+ bl.nd ___udivmodsi4
+ and.f 0,r6,2
+ sub.nz r1,0,r1
+ j.d r7
+ mov r0,r1
+#endif
+
+#endif /* L_modsi3 */
diff --git a/gnu/usr.bin/gcc/config/arc/t-arc b/gnu/usr.bin/gcc/config/arc/t-arc
new file mode 100644
index 00000000000..d922c27ca5f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arc/t-arc
@@ -0,0 +1,72 @@
+CROSS_LIBGCC1 = libgcc1-asm.a
+LIB1ASMSRC = arc/lib1funcs.asm
+LIB1ASMFUNCS = _mulsi3 _umulsidi3 _udivsi3 _divsi3 _umodsi3 _modsi3 _divmod_tools
+
+# We need libgcc routines to be mangled according to which cpu they
+# were compiled for.
+# ??? -mmangle-cpu passed by default for now.
+#LIBGCC2_CFLAGS = -g1 -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) -mmangle-cpu
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so...
+
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#ifndef __big_endian__' > dp-bit.c
+ echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
+ echo '#endif' >> dp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ echo '#ifndef __big_endian__' >> fp-bit.c
+ echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
+ echo '#endif' >> fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+# .init/.fini section routines
+
+x-crtinit.o: $(srcdir)/config/arc/initfini.c $(GCC_PASSES) $(CONFIG_H)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS) \
+ -DCRT_INIT -finhibit-size-directive -fno-inline-functions \
+ -g0 -c $(srcdir)/config/arc/initfini.c -o $(dir)/crtinit.o
+
+x-crtfini.o: $(srcdir)/config/arc/initfini.c $(GCC_PASSES) $(CONFIG_H)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS) \
+ -DCRT_FINI -finhibit-size-directive -fno-inline-functions \
+ -g0 -c $(srcdir)/config/arc/initfini.c -o $(dir)/crtfini.o
+
+MULTILIB_OPTIONS = EB
+MULTILIB_DIRNAMES = be
+
+# We need our own versions to build multiple copies of crt*.o.
+# ??? Use new support in Makefile.
+
+LIBGCC = stmp-multilib-arc
+INSTALL_LIBGCC = install-multilib-arc
+
+stmp-multilib-arc: stmp-multilib
+ for i in `$(GCC_FOR_TARGET) --print-multi-lib`; do \
+ dir=`echo $$i | sed -e 's/;.*$$//'`; \
+ flags=`echo $$i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; \
+ $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
+ CC="$(CC)" CFLAGS="$(CFLAGS)" \
+ HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \
+ GCC_CFLAGS="$(GCC_CFLAGS) $${flags}" \
+ INCLUDES="$(INCLUDES)" CRTSTUFF_T_CFLAGS=$(CRTSTUFF_T_CFLAGS) \
+ dir="$${dir}" x-crtinit.o x-crtfini.o; \
+ if [ $$? -eq 0 ] ; then true; else exit 1; fi; \
+ done
+ touch stmp-multilib-arc
+
+install-multilib-arc: install-multilib
+ for i in `$(GCC_FOR_TARGET) --print-multi-lib`; do \
+ dir=`echo $$i | sed -e 's/;.*$$//'`; \
+ rm -f $(libsubdir)/$${dir}/crtinit.o; \
+ $(INSTALL_DATA) $${dir}/crtinit.o $(libsubdir)/$${dir}/crtinit.o; \
+ chmod a-x $(libsubdir)/$${dir}/crtinit.o; \
+ rm -f $(libsubdir)/$${dir}/crtfini.o; \
+ $(INSTALL_DATA) $${dir}/crtfini.o $(libsubdir)/$${dir}/crtfini.o; \
+ chmod a-x $(libsubdir)/$${dir}/crtfini.o; \
+ done
diff --git a/gnu/usr.bin/gcc/config/arc/xm-arc.h b/gnu/usr.bin/gcc/config/arc/xm-arc.h
new file mode 100644
index 00000000000..ba011e94be6
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arc/xm-arc.h
@@ -0,0 +1,47 @@
+/* Configuration for GNU C-compiler for the ARC processor.
+ Copyright (C) 1994, 1997 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 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
+
+/* Doubles are stored in memory with the high order word first. This
+ matters when cross-compiling. */
+#define HOST_WORDS_BIG_ENDIAN 1
+
+/* target machine dependencies.
+ tm.h is a symbolic link to the actual target specific file. */
+#include "tm.h"
+
+/* Arguments to use with `exit'. */
+#define SUCCESS_EXIT_CODE 0
+#define FATAL_EXIT_CODE 33
+
+/* If compiled with Sun CC, the use of alloca requires this #include. */
+#ifndef __GNUC__
+#include "alloca.h"
+#endif
diff --git a/gnu/usr.bin/gcc/config/arm/aof.h b/gnu/usr.bin/gcc/config/arm/aof.h
new file mode 100644
index 00000000000..4d30defd5cf
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arm/aof.h
@@ -0,0 +1,453 @@
+/* Definitions of target machine for GNU compiler, for Advanced RISC Machines
+ ARM compilation, AOF Assembler.
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Richard Earnshaw (rearnsha@armltd.co.uk)
+
+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 AOF_ASSEMBLER
+
+#define LINK_LIBGCC_SPECIAL 1
+
+#define LINK_SPEC "%{aof} %{bin} %{aif} %{ihf} %{shl,*} %{reent*} %{split} \
+ %{ov*,*} %{reloc*} -nodebug"
+
+#define STARTFILE_SPEC "crtbegin.o%s"
+
+#define ENDFILE_SPEC "crtend.o%s"
+
+#ifndef ASM_SPEC
+#define ASM_SPEC "%{g -g} -arch 4 \
+-apcs 3%{mapcs-32:/32bit}%{mapcs-26:/26bit}%{!mapcs-26:%{!macps-32:/26bit}}"
+#endif
+
+#ifndef LIB_SPEC
+#define LIB_SPEC "%{Eb: armlib_h.32b%s}%{!Eb: armlib_h.32l%s}"
+#endif
+
+#define LIBGCC_SPEC "libgcc.a%s"
+
+/* Dividing the Output into Sections (Text, Data, ...) */
+/* AOF Assembler syntax is a nightmare when it comes to areas, since once
+ we change from one area to another, we can't go back again. Instead,
+ we must create a new area with the same attributes and add the new output
+ to that. Unfortunately, there is nothing we can do here to guarantee that
+ two areas with the same attributes will be linked adjacently in the
+ resulting executable, so we have to be careful not to do pc-relative
+ addressing across such boundaries. */
+char *aof_text_section ();
+#define TEXT_SECTION_ASM_OP aof_text_section ()
+
+#define SELECT_RTX_SECTION(MODE,RTX) text_section ();
+
+char *aof_data_section ();
+#define DATA_SECTION_ASM_OP aof_data_section ()
+
+#define EXTRA_SECTIONS in_zero_init, in_ctor, in_dtor, in_common
+
+#define EXTRA_SECTION_FUNCTIONS \
+ZERO_INIT_SECTION \
+CTOR_SECTION \
+DTOR_SECTION \
+COMMON_SECTION
+
+#define ZERO_INIT_SECTION \
+void \
+zero_init_section () \
+{ \
+ static int zero_init_count = 1; \
+ if (in_section != in_zero_init) \
+ { \
+ fprintf (asm_out_file, "\tAREA |C$$zidata%d|,NOINIT\n", \
+ zero_init_count++); \
+ in_section = in_zero_init; \
+ } \
+}
+
+#define CTOR_SECTION \
+void \
+ctor_section () \
+{ \
+ static int ctors_once = 0; \
+ if (in_section != in_ctor) \
+ { \
+ if (ctors_once) \
+ { \
+ fprintf (stderr, \
+ "Attempt to output more than one ctor section\n"); \
+ abort (); \
+ } \
+ fprintf (asm_out_file, "\t%s\n", CTORS_SECTION_ASM_OP); \
+ in_section = in_ctor; \
+ ctors_once = 1; \
+ } \
+}
+
+#define DTOR_SECTION \
+void \
+dtor_section () \
+{ \
+ static int dtors_once = 0; \
+ if (in_section != in_dtor) \
+ { \
+ if (dtors_once) \
+ { \
+ fprintf (stderr, \
+ "Attempt to output more than one dtor section\n"); \
+ abort (); \
+ } \
+ fprintf (asm_out_file, "\t%s\n", DTORS_SECTION_ASM_OP); \
+ in_section = in_dtor; \
+ dtors_once = 1; \
+ } \
+}
+
+/* Used by ASM_OUTPUT_COMMON (below) to tell varasm.c that we've
+ changed areas. */
+#define COMMON_SECTION \
+void \
+common_section () \
+{ \
+ static int common_count = 1; \
+ if (in_section != in_common) \
+ { \
+ in_section = in_common; \
+ } \
+}
+#define CTOR_LIST_BEGIN \
+asm (CTORS_SECTION_ASM_OP); \
+extern func_ptr __CTOR_END__[1]; \
+func_ptr __CTOR_LIST__[1] = {__CTOR_END__};
+
+#define CTOR_LIST_END \
+asm (CTORS_SECTION_ASM_OP); \
+func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
+
+#define DO_GLOBAL_CTORS_BODY \
+do { \
+ func_ptr *ptr = __CTOR_LIST__ + 1; \
+ while (*ptr) \
+ (*ptr++) (); \
+} while (0)
+
+#define DTOR_LIST_BEGIN \
+asm (DTORS_SECTION_ASM_OP); \
+extern func_ptr __DTOR_END__[1]; \
+func_ptr __DTOR_LIST__[1] = {__DTOR_END__};
+
+#define DTOR_LIST_END \
+asm (DTORS_SECTION_ASM_OP); \
+func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
+
+#define DO_GLOBAL_DTORS_BODY \
+do { \
+ func_ptr *ptr = __DTOR_LIST__ + 1; \
+ while (*ptr) \
+ (*ptr++) (); \
+} while (0)
+
+#define JUMP_TABLES_IN_TEXT_SECTION 1
+
+#ifndef ARM_OS_NAME
+#define ARM_OS_NAME "(generic)"
+#endif
+
+/* For the AOF linker, we need to reference __main to force the standard
+ library to get linked in. */
+
+#define ASM_FILE_START(STREAM) \
+{ \
+ extern char *version_string; \
+ fprintf ((STREAM), "%s Generated by gcc %s for ARM/%s\n", \
+ ASM_COMMENT_START, version_string, ARM_OS_NAME); \
+ fprintf ((STREAM), "__a1\tRN\t0\n"); \
+ fprintf ((STREAM), "__a2\tRN\t1\n"); \
+ fprintf ((STREAM), "__a3\tRN\t2\n"); \
+ fprintf ((STREAM), "__a4\tRN\t3\n"); \
+ fprintf ((STREAM), "__v1\tRN\t4\n"); \
+ fprintf ((STREAM), "__v2\tRN\t5\n"); \
+ fprintf ((STREAM), "__v3\tRN\t6\n"); \
+ fprintf ((STREAM), "__v4\tRN\t7\n"); \
+ fprintf ((STREAM), "__v5\tRN\t8\n"); \
+ fprintf ((STREAM), "__v6\tRN\t9\n"); \
+ fprintf ((STREAM), "__sl\tRN\t10\n"); \
+ fprintf ((STREAM), "__fp\tRN\t11\n"); \
+ fprintf ((STREAM), "__ip\tRN\t12\n"); \
+ fprintf ((STREAM), "__sp\tRN\t13\n"); \
+ fprintf ((STREAM), "__lr\tRN\t14\n"); \
+ fprintf ((STREAM), "__pc\tRN\t15\n"); \
+ fprintf ((STREAM), "__f0\tFN\t0\n"); \
+ fprintf ((STREAM), "__f1\tFN\t1\n"); \
+ fprintf ((STREAM), "__f2\tFN\t2\n"); \
+ fprintf ((STREAM), "__f3\tFN\t3\n"); \
+ fprintf ((STREAM), "__f4\tFN\t4\n"); \
+ fprintf ((STREAM), "__f5\tFN\t5\n"); \
+ fprintf ((STREAM), "__f6\tFN\t6\n"); \
+ fprintf ((STREAM), "__f7\tFN\t7\n"); \
+ text_section (); \
+}
+
+/* Some systems use __main in a way incompatible with its use in gcc, in these
+ cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
+ give the same symbol without quotes for an alternative entry point. You
+ must define both, or neither. */
+#define NAME__MAIN "__gccmain"
+#define SYMBOL__MAIN __gccmain
+
+#define ASM_FILE_END(STREAM) \
+do \
+{ \
+ if (flag_pic) \
+ aof_dump_pic_table (STREAM); \
+ aof_dump_imports (STREAM); \
+ fputs ("\tEND\n", (STREAM)); \
+} while (0);
+
+#define ASM_IDENTIFY_GCC(STREAM) fputs ("|gcc2_compiled.|\n", (STREAM))
+
+#define ASM_COMMENT_START ";"
+
+#define ASM_APP_ON ""
+
+#define ASM_APP_OFF ""
+
+#define ASM_OUTPUT_LONG_DOUBLE(STREAM,VALUE) \
+ ASM_OUTPUT_DOUBLE((STREAM),(VALUE))
+
+#define ASM_OUTPUT_DOUBLE(STREAM,VALUE) \
+do { \
+ char dstr[30]; \
+ long l[2]; \
+ REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), l); \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.14g", dstr); \
+ fprintf ((STREAM), "\tDCD &%lx, &%lx\t%s double %s\n", \
+ l[0], l[1], ASM_COMMENT_START, dstr); \
+} while (0)
+
+#define ASM_OUTPUT_FLOAT(STREAM,VALUE) \
+do { \
+ char dstr[30]; \
+ long l; \
+ REAL_VALUE_TO_TARGET_SINGLE ((VALUE), l); \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.7g", dstr); \
+ fprintf ((STREAM), "\tDCD &%lx\t%s double %s\n", \
+ l, ASM_COMMENT_START, dstr); \
+} while (0)
+
+#define ASM_OUTPUT_INT(STREAM,VALUE) \
+ (fprintf ((STREAM), "\tDCD\t"), \
+ output_addr_const ((STREAM), (VALUE)), \
+ fputc ('\n', (STREAM)))
+
+#define ASM_OUTPUT_SHORT(STREAM,VALUE) \
+ (fprintf ((STREAM), "\tDCW\t"), \
+ output_addr_const ((STREAM), (VALUE)), \
+ fputc ('\n', (STREAM)))
+
+#define ASM_OUTPUT_CHAR(STREAM,VALUE) \
+ (fprintf ((STREAM), "\tDCB\t"), \
+ output_addr_const ((STREAM), (VALUE)), \
+ fputc ('\n', (STREAM)))
+
+#define ASM_OUTPUT_BYTE(STREAM,VALUE) \
+ fprintf ((STREAM), "\tDCB\t%d\n", (VALUE))
+
+#define ASM_OUTPUT_ASCII(STREAM,PTR,LEN) \
+{ \
+ int i; \
+ char *ptr = (PTR); \
+ fprintf ((STREAM), "\tDCB"); \
+ for (i = 0; i < (LEN); i++) \
+ fprintf ((STREAM), " &%02x%s", \
+ (unsigned ) *(ptr++), \
+ (i + 1 < (LEN) \
+ ? ((i & 3) == 3 ? "\n\tDCB" : ",") \
+ : "\n")); \
+}
+
+#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == '\n')
+
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
+
+/* Output of Uninitialized Variables */
+
+#define ASM_OUTPUT_COMMON(STREAM,NAME,SIZE,ROUNDED) \
+ (common_section (), \
+ fprintf ((STREAM), "\tAREA "), \
+ assemble_name ((STREAM), (NAME)), \
+ fprintf ((STREAM), ", DATA, COMMON\n\t%% %d\t%s size=%d\n", \
+ (ROUNDED), ASM_COMMENT_START, SIZE))
+
+#define ASM_OUTPUT_LOCAL(STREAM,NAME,SIZE,ROUNDED) \
+ (zero_init_section (), \
+ assemble_name ((STREAM), (NAME)), \
+ fprintf ((STREAM), "\n"), \
+ fprintf ((STREAM), "\t%% %d\t%s size=%d\n", \
+ (ROUNDED), ASM_COMMENT_START, SIZE))
+
+/* Output and Generation of Labels */
+
+extern int arm_main_function;
+
+#define ASM_GLOBALIZE_LABEL(STREAM,NAME) \
+do { \
+ fprintf ((STREAM), "\tEXPORT\t"); \
+ assemble_name ((STREAM), (NAME)); \
+ fputc ('\n', (STREAM)); \
+ if ((NAME)[0] == 'm' && ! strcmp ((NAME), "main")) \
+ arm_main_function = 1; \
+} while (0)
+
+#define ASM_OUTPUT_LABEL(STREAM,NAME) \
+do { \
+ assemble_name (STREAM,NAME); \
+ fputs ("\n", STREAM); \
+} while (0)
+
+#define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL) \
+{ \
+ ASM_OUTPUT_LABEL (STREAM, NAME); \
+ if (! TREE_PUBLIC (DECL)) \
+ { \
+ fputs ("\tKEEP ", STREAM); \
+ ASM_OUTPUT_LABEL (STREAM, NAME); \
+ } \
+ aof_delete_import ((NAME)); \
+}
+
+#define ASM_DECLARE_OBJECT_NAME(STREAM,NAME,DECL) \
+{ \
+ ASM_OUTPUT_LABEL (STREAM, NAME); \
+ if (! TREE_PUBLIC (DECL)) \
+ { \
+ fputs ("\tKEEP ", STREAM); \
+ ASM_OUTPUT_LABEL (STREAM, NAME); \
+ } \
+ aof_delete_import ((NAME)); \
+}
+
+#define ASM_OUTPUT_EXTERNAL(STREAM,DECL,NAME) \
+ aof_add_import ((NAME))
+
+#define ASM_OUTPUT_EXTERNAL_LIBCALL(STREAM,SYMREF) \
+ (fprintf ((STREAM), "\tIMPORT\t"), \
+ assemble_name ((STREAM), XSTR ((SYMREF), 0)), \
+ fputc ('\n', (STREAM)))
+
+#define ASM_OUTPUT_LABELREF(STREAM,NAME) \
+ fprintf ((STREAM), "|%s|", NAME)
+
+#define ASM_GENERATE_INTERNAL_LABEL(STRING,PREFIX,NUM) \
+ sprintf ((STRING), "*|%s..%d|", (PREFIX), (NUM))
+
+#define ASM_FORMAT_PRIVATE_NAME(OUTVAR,NAME,NUMBER) \
+ ((OUTVAR) = (char *) alloca (strlen ((NAME)) + 10), \
+ sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER)))
+
+/* How initialization functions are handled */
+
+#define CTORS_SECTION_ASM_OP "AREA\t|C$$gnu_ctorsvec|, DATA, READONLY"
+#define DTORS_SECTION_ASM_OP "AREA\t|C$$gnu_dtorsvec|, DATA, READONLY"
+
+#define ASM_OUTPUT_CONSTRUCTOR(STREAM,NAME) \
+do { \
+ ctor_section (); \
+ fprintf ((STREAM), "\tDCD\t"); \
+ assemble_name ((STREAM), (NAME)); \
+ fputc ('\n', (STREAM)); \
+} while (0);
+
+#define ASM_OUTPUT_DESTRUCTOR(STREAM,NAME) \
+do { \
+ dtor_section (); \
+ fprintf ((STREAM), "\tDCD\t"); \
+ assemble_name ((STREAM), (NAME)); \
+ fputc ('\n', (STREAM)); \
+} while (0);
+
+/* Output of Assembler Instructions */
+
+#define REGISTER_NAMES \
+{ \
+ "a1", "a2", "a3", "a4", \
+ "v1", "v2", "v3", "v4", \
+ "v5", "v6", "sl", "fp", \
+ "ip", "sp", "lr", "pc", \
+ "f0", "f1", "f2", "f3", \
+ "f4", "f5", "f6", "f7", \
+ "cc", "sfp", "afp" \
+}
+
+#define ADDITIONAL_REGISTER_NAMES \
+{ \
+ {"r0", 0}, {"a1", 0}, \
+ {"r1", 1}, {"a2", 1}, \
+ {"r2", 2}, {"a3", 2}, \
+ {"r3", 3}, {"a4", 3}, \
+ {"r4", 4}, {"v1", 4}, \
+ {"r5", 5}, {"v2", 5}, \
+ {"r6", 6}, {"v3", 6}, \
+ {"r7", 7}, {"wr", 7}, \
+ {"r8", 8}, {"v5", 8}, \
+ {"r9", 9}, {"v6", 9}, \
+ {"r10", 10}, {"sl", 10}, {"v7", 10}, \
+ {"r11", 11}, {"fp", 11}, \
+ {"r12", 12}, {"ip", 12}, \
+ {"r13", 13}, {"sp", 13}, \
+ {"r14", 14}, {"lr", 14}, \
+ {"r15", 15}, {"pc", 15} \
+}
+
+#define REGISTER_PREFIX "__"
+#define USER_LABEL_PREFIX ""
+#define LOCAL_LABEL_PREFIX ""
+
+/* Output of Dispatch Tables */
+
+#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,VALUE,REL) \
+ fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE))
+
+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE) \
+ fprintf ((STREAM), "\tDCD\t|L..%d|\n", (VALUE))
+
+/* A label marking the start of a jump table is a data label. */
+#define ASM_OUTPUT_CASE_LABEL(STREAM,PREFIX,NUM,TABLE) \
+ fprintf ((STREAM), "\tALIGN\n|%s..%d|\n", (PREFIX), (NUM))
+
+/* Assembler Commands for Alignment */
+
+#define ASM_OUTPUT_SKIP(STREAM,NBYTES) \
+ fprintf ((STREAM), "\t%%\t%d\n", (NBYTES))
+
+#define ASM_OUTPUT_ALIGN(STREAM,POWER) \
+do { \
+ register int amount = 1 << (POWER); \
+ if (amount == 2) \
+ fprintf ((STREAM), "\tALIGN 2\n"); \
+ else if (amount == 4) \
+ fprintf ((STREAM), "\tALIGN\n"); \
+ else \
+ fprintf ((STREAM), "\tALIGN %d\n", amount); \
+} while (0)
+
+#include "arm/arm.h"
+
+#undef DBX_DEBUGGING_INFO
diff --git a/gnu/usr.bin/gcc/config/arm/aout.h b/gnu/usr.bin/gcc/config/arm/aout.h
new file mode 100644
index 00000000000..68e7227f7fc
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arm/aout.h
@@ -0,0 +1,259 @@
+/* Definitions of target machine for GNU compiler, for ARM with a.out
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Richard Earnshaw (rearnsha@armltd.co.uk).
+
+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 ARM_OS_NAME
+#define ARM_OS_NAME "(generic)"
+#endif
+
+/* The text to go at the start of the assembler file */
+#define ASM_FILE_START(STREAM) \
+{ \
+ fprintf (STREAM,"%srfp\t.req\t%sr9\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+ fprintf (STREAM,"%ssl\t.req\t%sr10\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+ fprintf (STREAM,"%sfp\t.req\t%sr11\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+ fprintf (STREAM,"%sip\t.req\t%sr12\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+ fprintf (STREAM,"%ssp\t.req\t%sr13\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+ fprintf (STREAM,"%slr\t.req\t%sr14\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+ fprintf (STREAM,"%spc\t.req\t%sr15\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+}
+
+#define ASM_APP_ON ""
+#define ASM_APP_OFF ""
+
+/* Switch to the text or data segment. */
+#define TEXT_SECTION_ASM_OP ".text"
+#define DATA_SECTION_ASM_OP ".data"
+#define BSS_SECTION_ASM_OP ".bss"
+
+#define REGISTER_PREFIX ""
+#define USER_LABEL_PREFIX "_"
+#define LOCAL_LABEL_PREFIX ""
+
+/* The assembler's names for the registers. */
+#ifndef REGISTER_NAMES
+#define REGISTER_NAMES \
+{ \
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc", \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "cc", "sfp", "afp" \
+}
+#endif
+
+#ifndef ADDITIONAL_REGISTER_NAMES
+#define ADDITIONAL_REGISTER_NAMES \
+{ \
+ {"a1", 0}, \
+ {"a2", 1}, \
+ {"a3", 2}, \
+ {"a4", 3}, \
+ {"v1", 4}, \
+ {"v2", 5}, \
+ {"v3", 6}, \
+ {"v4", 7}, \
+ {"v5", 8}, \
+ {"v6", 9}, \
+ {"rfp", 9}, /* Gcc used to call it this */ \
+ {"sb", 9}, \
+ {"v7", 10}, \
+ {"r10", 10}, /* sl */ \
+ {"r11", 11}, /* fp */ \
+ {"r12", 12}, /* ip */ \
+ {"r13", 13}, /* sp */ \
+ {"r14", 14}, /* lr */ \
+ {"r15", 15} /* pc */ \
+}
+#endif
+
+/* Arm Assembler barfs on dollars */
+#define DOLLARS_IN_IDENTIFIERS 0
+
+#define NO_DOLLAR_IN_LABEL
+
+/* DBX register number for a given compiler register number */
+#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+
+/* Generate DBX debugging information. riscix.h will undefine this because
+ the native assembler does not support stabs. */
+#define DBX_DEBUGGING_INFO 1
+
+/* Acorn dbx moans about continuation chars, so don't use any. */
+#ifndef DBX_CONTIN_LENGTH
+#define DBX_CONTIN_LENGTH 0
+#endif
+
+/* Output a source filename for the debugger. RISCiX dbx insists that the
+ ``desc'' field is set to compiler version number >= 315 (sic). */
+#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(STREAM,NAME) \
+do { \
+ fprintf (STREAM, ".stabs \"%s\",%d,0,315,%s\n", (NAME), N_SO, \
+ &ltext_label_name[1]); \
+ text_section (); \
+ ASM_OUTPUT_INTERNAL_LABEL (STREAM, "Ltext", 0); \
+} while (0)
+
+/* Output a function label definition. */
+#define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL) \
+ ASM_OUTPUT_LABEL(STREAM, NAME)
+
+#define ASM_OUTPUT_LABEL(STREAM,NAME) \
+do { \
+ assemble_name (STREAM,NAME); \
+ fputs (":\n", STREAM); \
+} while (0)
+
+/* Output a globalising directive for a label. */
+#define ASM_GLOBALIZE_LABEL(STREAM,NAME) \
+ (fprintf (STREAM, "\t.global\t"), \
+ assemble_name (STREAM, NAME), \
+ fputc ('\n',STREAM)) \
+
+/* Make an internal label into a string. */
+#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
+ sprintf (STRING, "*%s%s%d", LOCAL_LABEL_PREFIX, PREFIX, NUM)
+
+/* Nothing special is done about jump tables */
+/* #define ASM_OUTPUT_CASE_LABEL(STREAM,PREFIX,NUM,TABLE) */
+/* #define ASM_OUTPUT_CASE_END(STREAM,NUM,TABLE) */
+
+/* Construct a private name. */
+#define ASM_FORMAT_PRIVATE_NAME(OUTVAR,NAME,NUMBER) \
+ ((OUTVAR) = (char *) alloca (strlen (NAME) + 10), \
+ sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER)))
+
+/* Output an element of a dispatch table. */
+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE) \
+ fprintf (STREAM, "\t.word\t%sL%d\n", LOCAL_LABEL_PREFIX, VALUE)
+
+#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,VALUE,REL) \
+ fprintf (STREAM, "\tb\t%sL%d\n", LOCAL_LABEL_PREFIX, (VALUE))
+
+/* Output various types of constants. For real numbers we output hex, with
+ a comment containing the "human" value, this allows us to pass NaN's which
+ the riscix assembler doesn't understand (it also makes cross-assembling
+ less likely to fail). */
+
+#define ASM_OUTPUT_LONG_DOUBLE(STREAM,VALUE) \
+do { char dstr[30]; \
+ long l[3]; \
+ REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \
+ REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \
+ fprintf (STREAM, "\t.long 0x%lx,0x%lx,0x%lx\t%s long double %s\n", \
+ l[0], l[1], l[2], ASM_COMMENT_START, dstr); \
+ } while (0)
+
+
+#define ASM_OUTPUT_DOUBLE(STREAM, VALUE) \
+do { char dstr[30]; \
+ long l[2]; \
+ REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \
+ REAL_VALUE_TO_DECIMAL (VALUE, "%.14g", dstr); \
+ fprintf (STREAM, "\t.long 0x%lx, 0x%lx\t%s double %s\n", l[0], \
+ l[1], ASM_COMMENT_START, dstr); \
+ } while (0)
+
+#define ASM_OUTPUT_FLOAT(STREAM, VALUE) \
+do { char dstr[30]; \
+ long l; \
+ REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \
+ REAL_VALUE_TO_DECIMAL (VALUE, "%.7g", dstr); \
+ fprintf (STREAM, "\t.word 0x%lx\t%s float %s\n", l, \
+ ASM_COMMENT_START, dstr); \
+ } while (0);
+
+#define ASM_OUTPUT_INT(STREAM, EXP) \
+ { \
+ fprintf (STREAM, "\t.word\t"); \
+ OUTPUT_INT_ADDR_CONST (STREAM, (EXP)); \
+ fputc ('\n', STREAM); \
+ }
+
+#define ASM_OUTPUT_SHORT(STREAM, EXP) \
+ (fprintf (STREAM, "\t.short\t"), \
+ output_addr_const (STREAM, (EXP)), \
+ fputc ('\n', STREAM))
+
+#define ASM_OUTPUT_CHAR(STREAM, EXP) \
+ (fprintf (STREAM, "\t.byte\t"), \
+ output_addr_const (STREAM, (EXP)), \
+ fputc ('\n', STREAM))
+
+#define ASM_OUTPUT_BYTE(STREAM, VALUE) \
+ fprintf (STREAM, "\t.byte\t%d\n", VALUE)
+
+#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) \
+ output_ascii_pseudo_op ((STREAM), (unsigned char *)(PTR), (LEN))
+
+/* Output a gap. In fact we fill it with nulls. */
+#define ASM_OUTPUT_SKIP(STREAM, NBYTES) \
+ fprintf (STREAM, "\t.space\t%d\n", NBYTES)
+
+/* Align output to a power of two. Horrible /bin/as. */
+#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
+ do \
+ { \
+ register int amount = 1 << (POWER); \
+ \
+ if (amount == 2) \
+ fprintf (STREAM, "\t.even\n"); \
+ else if (amount != 1) \
+ fprintf (STREAM, "\t.align\t%d\n", amount - 4); \
+ } while (0)
+
+/* Output a common block */
+#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
+ (fprintf (STREAM, "\t.comm\t"), \
+ assemble_name ((STREAM), (NAME)), \
+ fprintf(STREAM, ", %d\t%s %d\n", ROUNDED, ASM_COMMENT_START, SIZE))
+
+/* Output a local common block. /bin/as can't do this, so hack a
+ `.space' into the bss segment. Note that this is *bad* practice. */
+#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM,NAME,SIZE,ALIGN) \
+ do { \
+ bss_section (); \
+ ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT)); \
+ ASM_OUTPUT_LABEL (STREAM, NAME); \
+ fprintf (STREAM, "\t.space\t%d\n", SIZE); \
+ } while (0)
+
+/* Output a zero-initialized block. */
+#define ASM_OUTPUT_ALIGNED_BSS(STREAM,DECL,NAME,SIZE,ALIGN) \
+ asm_output_aligned_bss(STREAM, DECL, NAME, SIZE, ALIGN)
+
+/* Output a source line for the debugger. */
+/* #define ASM_OUTPUT_SOURCE_LINE(STREAM,LINE) */
+
+/* Output a #ident directive. */
+#define ASM_OUTPUT_IDENT(STREAM,STRING) \
+ fprintf (STREAM,"- - - ident %s\n",STRING)
+
+/* The assembler's parentheses characters. */
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
+
+#ifndef ASM_COMMENT_START
+#define ASM_COMMENT_START "@"
+#endif
+
+/* This works for GAS and some other assemblers. */
+#define SET_ASM_OP ".set"
+
+#include "arm/arm.h"
diff --git a/gnu/usr.bin/gcc/config/arm/coff.h b/gnu/usr.bin/gcc/config/arm/coff.h
new file mode 100644
index 00000000000..92101588c8f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arm/coff.h
@@ -0,0 +1,209 @@
+/* Definitions of target machine for GNU compiler,
+ for ARM with COFF obj format.
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Doug Evans (dje@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 "arm/semi.h"
+
+/* Run-time Target Specification. */
+#undef TARGET_VERSION
+#define TARGET_VERSION fputs (" (ARM/coff)", stderr)
+
+/* ??? Maybe use --with{enable?}-fpu or some such to make hardware floating
+ point the default. NOT --nfp! --with{enable?} is supposed to replace it
+ (right?), so let's stop using it. */
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32)
+
+/* ??? Is a big-endian default intended to be supported? */
+#if 0 /*TARGET_CPU_DEFAULT & ARM_FLAG_BIG_END*/
+#define MULTILIB_DEFAULTS { "mbig-endian" }
+#else
+#define MULTILIB_DEFAULTS { "mlittle-endian" }
+#endif
+
+/* ??? Does arm.h really need to set this to 32? */
+#undef STRUCTURE_SIZE_BOUNDARY
+#define STRUCTURE_SIZE_BOUNDARY 8
+
+/* 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. */
+extern int arm_valid_machine_decl_attribute ();
+#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
+arm_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
+
+/* This is COFF, but prefer stabs. */
+#define SDB_DEBUGGING_INFO
+
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+#include "dbxcoff.h"
+
+#undef LOCAL_LABEL_PREFIX
+#define LOCAL_LABEL_PREFIX "."
+
+#undef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX ""
+
+/* A C statement to output assembler commands which will identify the
+ object file as having been compiled with GNU CC (or another GNU
+ compiler). */
+/* Define this to NULL so we don't get anything.
+ We have ASM_IDENTIFY_LANGUAGE.
+ Also, when using stabs, gcc2_compiled must be a stabs entry, not an
+ ordinary symbol, or gdb won't see it. The stabs entry must be
+ before the N_SO in order for gdb to find it. */
+#define ASM_IDENTIFY_GCC(STREAM)
+
+/* This outputs a lot of .req's to define alias for various registers.
+ Let's try to avoid this. */
+#undef ASM_FILE_START
+#define ASM_FILE_START(STREAM) \
+do { \
+ extern char *version_string; \
+ fprintf (STREAM, "%s Generated by gcc %s for ARM/coff\n", \
+ ASM_COMMENT_START, version_string); \
+} while (0)
+
+/* A C statement to output something to the assembler file to switch to section
+ NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
+ NULL_TREE. Some target formats do not support arbitrary sections. Do not
+ define this macro in such cases. */
+#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
+do { \
+ if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \
+ fprintf (STREAM, "\t.section %s,\"x\"\n", (NAME)); \
+ else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC)) \
+ fprintf (STREAM, "\t.section %s,\"\"\n", (NAME)); \
+ else \
+ fprintf (STREAM, "\t.section %s,\"w\"\n", (NAME)); \
+} while (0)
+
+/* Support the ctors/dtors and other sections. */
+
+#undef INIT_SECTION_ASM_OP
+
+/* Define this macro if jump tables (for `tablejump' insns) should be
+ output in the text section, along with the assembler instructions.
+ Otherwise, the readonly data section is used. */
+#define JUMP_TABLES_IN_TEXT_SECTION
+
+#undef READONLY_DATA_SECTION
+#define READONLY_DATA_SECTION rdata_section
+#undef RDATA_SECTION_ASM_OP
+#define RDATA_SECTION_ASM_OP "\t.section .rdata"
+
+#undef CTORS_SECTION_ASM_OP
+#define CTORS_SECTION_ASM_OP "\t.section .ctors,\"x\""
+#undef DTORS_SECTION_ASM_OP
+#define DTORS_SECTION_ASM_OP "\t.section .dtors,\"x\""
+
+/* A list of other sections which the compiler might be "in" at any
+ given time. */
+
+#undef EXTRA_SECTIONS
+#define EXTRA_SECTIONS SUBTARGET_EXTRA_SECTIONS in_rdata, in_ctors, in_dtors
+
+#define SUBTARGET_EXTRA_SECTIONS
+
+/* A list of extra section function definitions. */
+
+#undef EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS \
+ RDATA_SECTION_FUNCTION \
+ CTORS_SECTION_FUNCTION \
+ DTORS_SECTION_FUNCTION \
+ SUBTARGET_EXTRA_SECTION_FUNCTIONS
+
+#define SUBTARGET_EXTRA_SECTION_FUNCTIONS
+
+#define RDATA_SECTION_FUNCTION \
+void \
+rdata_section () \
+{ \
+ if (in_section != in_rdata) \
+ { \
+ fprintf (asm_out_file, "%s\n", RDATA_SECTION_ASM_OP); \
+ in_section = in_rdata; \
+ } \
+}
+
+#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; \
+ } \
+}
+
+/* Support the ctors/dtors sections for g++. */
+
+#define INT_ASM_OP ".word"
+
+/* A C statement (sans semicolon) to output an element in the table of
+ global constructors. */
+#undef ASM_OUTPUT_CONSTRUCTOR
+#define ASM_OUTPUT_CONSTRUCTOR(STREAM,NAME) \
+do { \
+ ctors_section (); \
+ fprintf (STREAM, "\t%s\t ", INT_ASM_OP); \
+ assemble_name (STREAM, NAME); \
+ fprintf (STREAM, "\n"); \
+} while (0)
+
+/* A C statement (sans semicolon) to output an element in the table of
+ global destructors. */
+#undef ASM_OUTPUT_DESTRUCTOR
+#define ASM_OUTPUT_DESTRUCTOR(STREAM,NAME) \
+do { \
+ dtors_section (); \
+ fprintf (STREAM, "\t%s\t ", INT_ASM_OP); \
+ assemble_name (STREAM, NAME); \
+ fprintf (STREAM, "\n"); \
+} while (0)
+
+/* __CTOR_LIST__ and __DTOR_LIST__ must be defined by the linker script. */
+#define CTOR_LISTS_DEFINED_EXTERNALLY
+
+#undef DO_GLOBAL_CTORS_BODY
+#undef DO_GLOBAL_DTORS_BODY
+
+/* The ARM development system has atexit and doesn't have _exit,
+ so define this for now. */
+#define HAVE_ATEXIT
+
+/* The ARM development system defines __main. */
+#define NAME__MAIN "__gccmain"
+#define SYMBOL__MAIN __gccmain
diff --git a/gnu/usr.bin/gcc/config/arm/linux-gas.h b/gnu/usr.bin/gcc/config/arm/linux-gas.h
new file mode 100644
index 00000000000..ea8b4f0a37e
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arm/linux-gas.h
@@ -0,0 +1,34 @@
+/* Definitions of target machine for GNU compiler. ARM Linux-based GNU
+ systems version.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Russell King <rmk92@ecs.soton.ac.uk>.
+
+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 this program; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Limit the length of a stabs entry (for the broken Acorn assembler) */
+#define DBX_CONTIN_LENGTH 80
+
+#include "arm/linux.h"
+
+/*
+ * We are using GAS, so stabs should work.
+ */
+
+#ifndef DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
+#endif
diff --git a/gnu/usr.bin/gcc/config/arm/linux.h b/gnu/usr.bin/gcc/config/arm/linux.h
new file mode 100644
index 00000000000..fa8fef10e72
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arm/linux.h
@@ -0,0 +1,72 @@
+/* Definitions for ARM running Linux-based GNU systems.
+ Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
+ Contributed by Russell King <rmk92@ecs.soton.ac.uk>.
+
+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 this program; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include <linux-aout.h>
+
+/* these are different... */
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+"%{pg:gcrt0.o%s} %{!pg:%{p:gcrt0.o%s} %{!p:crt0.o%s}} %{static:-static}"
+
+#undef ASM_APP_ON
+#undef ASM_APP_OFF
+#undef COMMENT_BEGIN
+
+/* We default to ARM3. */
+#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm3
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES \
+"-Dunix -Darm -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(arm) -Amachine(arm)"
+
+#undef LIB_SPEC
+#define LIB_SPEC \
+ "%{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} %{!ggdb:-lc} %{ggdb:-lg}"
+
+#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
+
+#define HANDLE_SYSV_PRAGMA
+
+/* Run-time Target Specification. */
+#define TARGET_VERSION fputs (" (ARM GNU/Linux with a.out)", stderr);
+
+/* This is used in ASM_FILE_START */
+#define ARM_OS_NAME "Linux"
+
+/* Unsigned chars produces much better code than signed. */
+#define DEFAULT_SIGNED_CHAR 0
+
+/* Maths operation domain error number, EDOM */
+#define TARGET_EDOM 33
+#include "arm/aout.h"
+
+#undef SUBTARGET_CPP_SPEC
+#define SUBTARGET_CPP_SPEC "%{posix:-D_POSIX_SOURCE}"
diff --git a/gnu/usr.bin/gcc/config/arm/netbsd.h b/gnu/usr.bin/gcc/config/arm/netbsd.h
new file mode 100644
index 00000000000..94fd024d42e
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arm/netbsd.h
@@ -0,0 +1,143 @@
+/* NetBSD/arm (RiscBSD) version.
+ Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
+ Contributed by Mark Brinicombe (amb@physig.ph.kcl.ac.uk)
+
+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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Run-time Target Specification. */
+#define TARGET_VERSION fputs (" (ARM/NetBSD)", stderr);
+
+/* This is used in ASM_FILE_START. */
+#define ARM_OS_NAME "NetBSD"
+
+/* Unsigned chars produces much better code than signed. */
+#define DEFAULT_SIGNED_CHAR 0
+
+/* Since we always use GAS as our assembler we support stabs. */
+#define DBX_DEBUGGING_INFO 1
+
+/*#undef ASM_DECLARE_FUNCTION_NAME*/
+
+/* ARM6 family default cpu. */
+#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm6
+
+/* Default is to use APCS-32 mode. */
+#define TARGET_DEFAULT ARM_FLAG_APCS_32
+
+#include "arm/aout.h"
+
+/* This gets redefined in config/netbsd.h. */
+#undef TARGET_MEM_FUNCTIONS
+
+#include <netbsd.h>
+
+/* Some defines for CPP.
+ arm32 is the NetBSD port name, so we always define arm32 and __arm32__. */
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "\
+-Dunix -Driscbsd -Darm32 -D__arm32__ -D__arm__ -D__NetBSD__ \
+-Asystem(unix) -Asystem(NetBSD) -Acpu(arm) -Amachine(arm)"
+
+/* Define _POSIX_SOURCE if necessary. */
+#undef CPP_SPEC
+#define CPP_SPEC "\
+%(cpp_cpu_arch) %(cpp_apcs_pc) %(cpp_float) %(cpp_endian) \
+%{posix:-D_POSIX_SOURCE} \
+"
+
+/* Because TARGET_DEFAULT sets ARM_FLAG_APCS_32 */
+#undef CPP_APCS_PC_DEFAULT_SPEC
+#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
+
+/* Pass -X to the linker so that it will strip symbols starting with 'L' */
+#undef LINK_SPEC
+#define LINK_SPEC "\
+-X %{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{R*} \
+%{static:-Bstatic} %{assert*} \
+"
+
+#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
+
+/* We don't have any limit on the length as out debugger is GDB. */
+#undef DBX_CONTIN_LENGTH
+
+/* NetBSD does its profiling differently to the Acorn compiler. We
+ don't need a word following the mcount call; and to skip it
+ requires either an assembly stub or use of fomit-frame-pointer when
+ compiling the profiling functions. Since we break Acorn CC
+ compatibility below a little more won't hurt. */
+
+#undef FUNCTION_PROFILER
+#define FUNCTION_PROFILER(STREAM,LABELNO) \
+{ \
+ fprintf(STREAM, "\tmov\t%sip, %slr\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+ fprintf(STREAM, "\tbl\tmcount\n"); \
+}
+
+/* On the ARM `@' introduces a comment, so we must use something else
+ for .type directives. */
+#undef TYPE_OPERAND_FMT
+#define TYPE_OPERAND_FMT "%%%s"
+
+/* VERY BIG NOTE : Change of structure alignment for RiscBSD.
+ There are consequences you should be aware of...
+
+ Normally GCC/arm uses a structure alignment of 32 for compatibility
+ with armcc. This means that structures are padded to a word
+ boundary. However this causes problems with bugged NetBSD kernel
+ code (possibly userland code as well - I have not checked every
+ binary). The nature of this bugged code is to rely on sizeof()
+ returning the correct size of various structures rounded to the
+ nearest byte (SCSI and ether code are two examples, the vm system
+ is another). This code breaks when the structure alignment is 32
+ as sizeof() will report a word=rounded size. By changing the
+ structure alignment to 8. GCC will conform to what is expected by
+ NetBSD.
+
+ This has several side effects that should be considered.
+ 1. Structures will only be aligned to the size of the largest member.
+ i.e. structures containing only bytes will be byte aligned.
+ structures containing shorts will be half word alinged.
+ structures containing ints will be word aligned.
+
+ This means structures should be padded to a word boundary if
+ alignment of 32 is required for byte structures etc.
+
+ 2. A potential performance penalty may exist if strings are no longer
+ word aligned. GCC will not be able to use word load/stores to copy
+ short strings.
+
+ This modification is not encouraged but with the present state of the
+ NetBSD source tree it is currently the only solution that meets the
+ requirements. */
+#undef STRUCTURE_SIZE_BOUNDARY
+#define STRUCTURE_SIZE_BOUNDARY 8
diff --git a/gnu/usr.bin/gcc/config/arm/semiaof.h b/gnu/usr.bin/gcc/config/arm/semiaof.h
new file mode 100644
index 00000000000..b16d37803fa
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arm/semiaof.h
@@ -0,0 +1,43 @@
+/* Definitions of target machine for GNU compiler. ARM on semi-hosted platform
+ AOF Syntax assembler.
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Richard Earnshaw (richard.earnshaw@armltd.co.uk)
+
+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 CPP_PREDEFINES \
+ "-Darm -Dsemi -Acpu(arm) -Amachine(arm)"
+
+#define ASM_SPEC "%{g -g} -arch 4 \
+-apcs 3%{mapcs-32:/32bit}%{mapcs-26:/26bit}%{!mapcs-26:%{!macps-32:/32bit}}"
+
+#define LIB_SPEC "%{Eb: armlib_h.32b%s}%{!Eb: armlib_h.32l%s}"
+
+#define TARGET_VERSION fputs (" (ARM/semi-hosted)", stderr);
+
+#define TARGET_DEFAULT ARM_FLAG_APCS_32
+
+/* The Norcroft C library defines size_t as "unsigned int" */
+#define SIZE_TYPE "unsigned int"
+
+#include "arm/aof.h"
+
+#undef CPP_APCS_PC_DEFAULT_SPEC
+#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
+
+
diff --git a/gnu/usr.bin/gcc/config/arm/t-bare b/gnu/usr.bin/gcc/config/arm/t-bare
new file mode 100644
index 00000000000..85e6a301aa7
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arm/t-bare
@@ -0,0 +1,30 @@
+CROSS_LIBGCC1 = libgcc1-asm.a
+LIB1ASMSRC = arm/lib1funcs.asm
+LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so...
+
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ echo '#ifndef __ARMEB__' >> fp-bit.c
+ echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
+ echo '#endif' >> fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#ifndef __ARMEB__' > dp-bit.c
+ echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
+ echo '#define FLOAT_WORD_ORDER_MISMATCH' >> dp-bit.c
+ echo '#endif' >> dp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> dp-bit.c
+
+# Avoid building a duplicate set of libraries for the default endian-ness.
+MULTILIB_OPTIONS = mlittle-endian/mbig-endian mhard-float
+MULTILIB_DIRNAMES = le be fpu
+MULTILIB_MATCHES =
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
diff --git a/gnu/usr.bin/gcc/config/arm/t-linux b/gnu/usr.bin/gcc/config/arm/t-linux
new file mode 100644
index 00000000000..f45e3147e98
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arm/t-linux
@@ -0,0 +1,19 @@
+# Just for these, we omit the frame pointer since it makes such a big
+# difference. It is then pointless adding debugging.
+LIBGCC2_CFLAGS=-O2 -fomit-frame-pointer $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) -g0
+
+# Don't build enquire
+ENQUIRE=
+
+# Since libgcc1 is an assembler file, we can build it automatically for the
+# cross-compiler.
+CROSS_LIBGCC1 = libgcc1-asm.a
+LIBGCC1 = libgcc1-asm.a
+LIB1ASMSRC = arm/lib1funcs.asm
+LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
+
+MULTILIB_OPTIONS = mapcs-32
+MULTILIB_DIRNAMES = apcs-32
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
diff --git a/gnu/usr.bin/gcc/config/arm/t-netbsd b/gnu/usr.bin/gcc/config/arm/t-netbsd
new file mode 100644
index 00000000000..cc2f6583679
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arm/t-netbsd
@@ -0,0 +1,7 @@
+# Just for these, we omit the frame pointer since it makes such a big
+# difference. It is then pointless adding debugging.
+LIBGCC2_CFLAGS=-O2 -fomit-frame-pointer $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) -g0
+# -Dinhibit_libc
+
+# Don't build enquire
+ENQUIRE=
diff --git a/gnu/usr.bin/gcc/config/arm/t-semiaof b/gnu/usr.bin/gcc/config/arm/t-semiaof
new file mode 100644
index 00000000000..6f1dfca081c
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arm/t-semiaof
@@ -0,0 +1,63 @@
+OLDCC = armcc -w
+# Don't build enquire
+ENQUIRE=
+CROSS_LIBGCC1 = libgcc1-aof.a
+LIBGCC2 = libgcc2-aof.a
+LIBGCC = libgcc-aof.a
+LIBGCC2_CFLAGS = -O2 -fomit-frame-pointer
+LIBGCC1_TEST = #libgcc1-atest
+EXTRA_PARTS = crtbegin.o crtend.o
+
+# Rule to build libgcc1.a and libgcc2.a and libgcc.a, since the librarian
+# for the ARM tools is somewhat quirky, and needs a special rule to use it.
+libgcc1-aof.a: libgcc1.c $(CONFIG_H) config.status
+ -rm -rf tmplib libgcc1.a libgcc1-aof.a tmplibgcc1.a
+ mkdir tmplib
+ for name in $(LIB1FUNCS); \
+ do \
+ echo $${name}; \
+ rm -f $${name}$(objext); \
+ $(OLDCC) $(CCLIBFLAGS) $(INCLUDES) -c -DL$${name} $(srcdir)/libgcc1.c; \
+ if [ $$? -eq 0 ] ; then true; else exit 1; fi; \
+ mv libgcc1$(objext) tmplib/$${name}$(objext); \
+ done
+ (cd tmplib; \
+ armlib -c tmplibgcc1.a *; \
+ mv tmplibgcc1.a ..)
+ mv tmplibgcc1.a libgcc1-aof.a
+ rm -rf tmplib
+
+libgcc2-aof.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(LIB2FUNCS_EXTRA) \
+ machmode.h longlong.h gbl-ctors.h config.status
+ -rm -f tmplibgcc2.a
+ -rm -rf tmplib
+ mkdir tmplib
+ for name in $(LIB2FUNCS); \
+ do \
+ echo $${name}; \
+ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -c -DL$${name} \
+ $(srcdir)/libgcc2.c -o tmplib/$${name}$(objext); \
+ if [ $$? -eq 0 ] ; then true; else exit 1; fi; \
+ done
+ (cd tmplib; \
+ armlib -c tmplibgcc2.a *; \
+ mv tmplibgcc2.a ..)
+ mv tmplibgcc2.a libgcc2-aof.a
+ rm -rf tmplib
+
+# Combine the various libraries into a single library, libgcc.a.
+libgcc-aof.a: $(CROSS_LIBGCC1) $(LIBGCC2)
+ -rm -rf tmplibgcc.a libgcc.a tmpcopy libgcc-aof.a
+ mkdir tmpcopy
+ (cd tmpcopy; armlib -e ../$(LIBGCC1) \*)
+ -(cd tmpcopy; chmod +w * > /dev/null 2>&1)
+ (cd tmpcopy; armlib -e ../$(LIBGCC2) \*)
+ (cd tmpcopy; armlib -co ../tmplibgcc.a *$(objext))
+ rm -rf tmpcopy
+ mv tmplibgcc.a libgcc.a
+ ln libgcc.a libgcc-aof.a
+
+libgcc1-atest: libgcc1-test.o native $(GCC_PARTS) $(EXTRA_PARTS)
+ @echo "Testing libgcc1. Ignore linker warning messages."
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) libgcc1-test.o -o libgcc1-test \
+ -v
diff --git a/gnu/usr.bin/gcc/config/arm/xm-linux.h b/gnu/usr.bin/gcc/config/arm/xm-linux.h
new file mode 100644
index 00000000000..ca120a9c8a6
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arm/xm-linux.h
@@ -0,0 +1,24 @@
+/* Configuration for GCC for Intel i386 running Linux-based GNU systems./
+ Copyright (C) 1993, 1994, 1995, 1997 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 <arm/xm-arm.h>
+#include <xm-linux.h>
+
diff --git a/gnu/usr.bin/gcc/config/arm/xm-netbsd.h b/gnu/usr.bin/gcc/config/arm/xm-netbsd.h
new file mode 100644
index 00000000000..ea9a64ea4bf
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/arm/xm-netbsd.h
@@ -0,0 +1,7 @@
+/* Configuration for GCC for ARM running NetBSD as host. */
+
+#include <arm/xm-arm.h>
+
+#ifndef SYS_SIGLIST_DECLARED
+#define SYS_SIGLIST_DECLARED
+#endif
diff --git a/gnu/usr.bin/gcc/config/dbx.h b/gnu/usr.bin/gcc/config/dbx.h
new file mode 100644
index 00000000000..c5cd3b5f2d0
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/dbx.h
@@ -0,0 +1,30 @@
+/* Prefer DBX (stabs) debugging information.
+ Copyright (C) 1996 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 causes gcc to prefer using DBX (stabs) debugging
+ information. The configure script will add a #include of this file
+ to tm.h when --with-stabs is used for certain targets. */
+
+#ifndef DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO
+#endif
+
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
diff --git a/gnu/usr.bin/gcc/config/dbxcoff.h b/gnu/usr.bin/gcc/config/dbxcoff.h
new file mode 100644
index 00000000000..9497a70b83f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/dbxcoff.h
@@ -0,0 +1,87 @@
+/* Definitions needed when using stabs embedded in COFF sections.
+ Copyright (C) 1996 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 may be included by any COFF target which wishes to
+ support -gstabs generating stabs in sections, as produced by gas
+ and understood by gdb. */
+
+/* Output DBX (stabs) debugging information if doing -gstabs. */
+
+#undef DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO
+
+/* Generate SDB debugging information by default. */
+
+#ifndef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
+#endif
+
+/* Be function-relative for block and source line stab directives. */
+
+#undef DBX_BLOCKS_FUNCTION_RELATIVE
+#define DBX_BLOCKS_FUNCTION_RELATIVE 1
+
+/* but, to make this work, functions must appear prior to line info. */
+
+#undef DBX_FUNCTION_FIRST
+#define DBX_FUNCTION_FIRST
+
+/* Generate a blank trailing N_SO to mark the end of the .o file, since
+ we can't depend upon the linker to mark .o file boundaries with
+ embedded stabs. */
+
+#undef DBX_OUTPUT_MAIN_SOURCE_FILE_END
+#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
+ fprintf (FILE, \
+ "\t.text\n\t.stabs \"\",%d,0,0,Letext\nLetext:\n", N_SO)
+
+/* Like block addresses, stabs line numbers are relative to the
+ current function. */
+
+#undef ASM_OUTPUT_SOURCE_LINE
+#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \
+{ if (write_symbols == SDB_DEBUG) { \
+ fprintf ((FILE), "\t.ln\t%d\n", \
+ ((sdb_begin_function_line > -1) \
+ ? (LINE) - sdb_begin_function_line : 1)); \
+ } else if (write_symbols == DBX_DEBUG) { \
+ static int sym_lineno = 1; \
+ char buffer[256]; \
+ ASM_GENERATE_INTERNAL_LABEL (buffer, "LM", sym_lineno); \
+ fprintf (FILE, ".stabn 68,0,%d,", LINE); \
+ assemble_name (FILE, buffer); \
+ putc ('-', FILE); \
+ assemble_name (FILE, \
+ XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
+ putc ('\n', FILE); \
+ ASM_OUTPUT_INTERNAL_LABEL (FILE, "LM", sym_lineno); \
+ sym_lineno++; \
+ } }
+
+/* When generating stabs debugging, use N_BINCL entries. */
+
+#undef DBX_USE_BINCL
+#define DBX_USE_BINCL
+
+/* There is no limit to the length of stabs strings. */
+
+#ifndef DBX_CONTIN_LENGTH
+#define DBX_CONTIN_LENGTH 0
+#endif
diff --git a/gnu/usr.bin/gcc/config/float-i128.h b/gnu/usr.bin/gcc/config/float-i128.h
new file mode 100644
index 00000000000..6a9dd48b1a3
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/float-i128.h
@@ -0,0 +1,96 @@
+/* float.h for target with IEEE 32, 64 and 128 bit floating point formats */
+#ifndef _FLOAT_H_
+#define _FLOAT_H_
+/* Produced by enquire version 4.3, CWI, Amsterdam */
+
+ /* Radix of exponent representation */
+#undef FLT_RADIX
+#define FLT_RADIX 2
+ /* Number of base-FLT_RADIX digits in the significand of a float */
+#undef FLT_MANT_DIG
+#define FLT_MANT_DIG 24
+ /* Number of decimal digits of precision in a float */
+#undef FLT_DIG
+#define FLT_DIG 6
+ /* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown */
+#undef FLT_ROUNDS
+#define FLT_ROUNDS 1
+ /* Difference between 1.0 and the minimum float greater than 1.0 */
+#undef FLT_EPSILON
+#define FLT_EPSILON 1.19209290e-07F
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */
+#undef FLT_MIN_EXP
+#define FLT_MIN_EXP (-125)
+ /* Minimum normalised float */
+#undef FLT_MIN
+#define FLT_MIN 1.17549435e-38F
+ /* Minimum int x such that 10**x is a normalised float */
+#undef FLT_MIN_10_EXP
+#define FLT_MIN_10_EXP (-37)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable float */
+#undef FLT_MAX_EXP
+#define FLT_MAX_EXP 128
+ /* Maximum float */
+#undef FLT_MAX
+#define FLT_MAX 3.40282347e+38F
+ /* Maximum int x such that 10**x is a representable float */
+#undef FLT_MAX_10_EXP
+#define FLT_MAX_10_EXP 38
+
+ /* Number of base-FLT_RADIX digits in the significand of a double */
+#undef DBL_MANT_DIG
+#define DBL_MANT_DIG 53
+ /* Number of decimal digits of precision in a double */
+#undef DBL_DIG
+#define DBL_DIG 15
+ /* Difference between 1.0 and the minimum double greater than 1.0 */
+#undef DBL_EPSILON
+#define DBL_EPSILON 2.2204460492503131e-16
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */
+#undef DBL_MIN_EXP
+#define DBL_MIN_EXP (-1021)
+ /* Minimum normalised double */
+#undef DBL_MIN
+#define DBL_MIN 2.2250738585072014e-308
+ /* Minimum int x such that 10**x is a normalised double */
+#undef DBL_MIN_10_EXP
+#define DBL_MIN_10_EXP (-307)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable double */
+#undef DBL_MAX_EXP
+#define DBL_MAX_EXP 1024
+ /* Maximum double */
+#undef DBL_MAX
+#define DBL_MAX 1.7976931348623157e+308
+ /* Maximum int x such that 10**x is a representable double */
+#undef DBL_MAX_10_EXP
+#define DBL_MAX_10_EXP 308
+
+ /* Number of base-FLT_RADIX digits in the significand of a long double */
+#undef LDBL_MANT_DIG
+#define LDBL_MANT_DIG 113
+ /* Number of decimal digits of precision in a long double */
+#undef LDBL_DIG
+#define LDBL_DIG 33
+ /* Difference between 1.0 and the minimum long double greater than 1.0 */
+#undef LDBL_EPSILON
+#define LDBL_EPSILON 1.925929944387235853055977942584927319E-34L
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised long double */
+#undef LDBL_MIN_EXP
+#define LDBL_MIN_EXP (-16381)
+ /* Minimum normalised long double */
+#undef LDBL_MIN
+#define LDBL_MIN 3.362103143112093506262677817321752603E-4932L
+ /* Minimum int x such that 10**x is a normalised long double */
+#undef LDBL_MIN_10_EXP
+#define LDBL_MIN_10_EXP (-4931)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable long double */
+#undef LDBL_MAX_EXP
+#define LDBL_MAX_EXP 16384
+ /* Maximum long double */
+#undef LDBL_MAX
+#define LDBL_MAX 1.189731495357231765085759326628007016E+4932L
+ /* Maximum int x such that 10**x is a representable long double */
+#undef LDBL_MAX_10_EXP
+#define LDBL_MAX_10_EXP 4932
+
+#endif /* _FLOAT_H_ */
diff --git a/gnu/usr.bin/gcc/config/float-i32.h b/gnu/usr.bin/gcc/config/float-i32.h
new file mode 100644
index 00000000000..c834926b085
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/float-i32.h
@@ -0,0 +1,96 @@
+/* float.h for target with only IEEE 32 bit floating point format */
+#ifndef _FLOAT_H_
+#define _FLOAT_H_
+/* Produced by enquire version 4.3, CWI, Amsterdam */
+
+ /* Radix of exponent representation */
+#undef FLT_RADIX
+#define FLT_RADIX 2
+ /* Number of base-FLT_RADIX digits in the significand of a float */
+#undef FLT_MANT_DIG
+#define FLT_MANT_DIG 24
+ /* Number of decimal digits of precision in a float */
+#undef FLT_DIG
+#define FLT_DIG 6
+ /* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown */
+#undef FLT_ROUNDS
+#define FLT_ROUNDS 1
+ /* Difference between 1.0 and the minimum float greater than 1.0 */
+#undef FLT_EPSILON
+#define FLT_EPSILON 1.19209290e-07F
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */
+#undef FLT_MIN_EXP
+#define FLT_MIN_EXP (-125)
+ /* Minimum normalised float */
+#undef FLT_MIN
+#define FLT_MIN 1.17549435e-38F
+ /* Minimum int x such that 10**x is a normalised float */
+#undef FLT_MIN_10_EXP
+#define FLT_MIN_10_EXP (-37)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable float */
+#undef FLT_MAX_EXP
+#define FLT_MAX_EXP 128
+ /* Maximum float */
+#undef FLT_MAX
+#define FLT_MAX 3.40282347e+38F
+ /* Maximum int x such that 10**x is a representable float */
+#undef FLT_MAX_10_EXP
+#define FLT_MAX_10_EXP 38
+
+ /* Number of base-FLT_RADIX digits in the significand of a double */
+#undef DBL_MANT_DIG
+#define DBL_MANT_DIG 24
+ /* Number of decimal digits of precision in a double */
+#undef DBL_DIG
+#define DBL_DIG 6
+ /* Difference between 1.0 and the minimum double greater than 1.0 */
+#undef DBL_EPSILON
+#define DBL_EPSILON 1.19209290e-07F
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */
+#undef DBL_MIN_EXP
+#define DBL_MIN_EXP (-125)
+ /* Minimum normalised double */
+#undef DBL_MIN
+#define DBL_MIN 1.17549435e-38F
+ /* Minimum int x such that 10**x is a normalised double */
+#undef DBL_MIN_10_EXP
+#define DBL_MIN_10_EXP (-37)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable double */
+#undef DBL_MAX_EXP
+#define DBL_MAX_EXP 128
+ /* Maximum double */
+#undef DBL_MAX
+#define DBL_MAX 3.40282347e+38F
+ /* Maximum int x such that 10**x is a representable double */
+#undef DBL_MAX_10_EXP
+#define DBL_MAX_10_EXP 38
+
+ /* Number of base-FLT_RADIX digits in the significand of a long double */
+#undef LDBL_MANT_DIG
+#define LDBL_MANT_DIG 24
+ /* Number of decimal digits of precision in a long double */
+#undef LDBL_DIG
+#define LDBL_DIG 6
+ /* Difference between 1.0 and the minimum long double greater than 1.0 */
+#undef LDBL_EPSILON
+#define LDBL_EPSILON 1.19209290e-07F
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised long double */
+#undef LDBL_MIN_EXP
+#define LDBL_MIN_EXP (-125)
+ /* Minimum normalised long double */
+#undef LDBL_MIN
+#define LDBL_MIN 1.17549435e-38F
+ /* Minimum int x such that 10**x is a normalised long double */
+#undef LDBL_MIN_10_EXP
+#define LDBL_MIN_10_EXP (-37)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable long double */
+#undef LDBL_MAX_EXP
+#define LDBL_MAX_EXP 128
+ /* Maximum long double */
+#undef LDBL_MAX
+#define LDBL_MAX 3.40282347e+38F
+ /* Maximum int x such that 10**x is a representable long double */
+#undef LDBL_MAX_10_EXP
+#define LDBL_MAX_10_EXP 38
+
+#endif /* _FLOAT_H_ */
diff --git a/gnu/usr.bin/gcc/config/float-i64.h b/gnu/usr.bin/gcc/config/float-i64.h
new file mode 100644
index 00000000000..7dbe4e92a10
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/float-i64.h
@@ -0,0 +1,96 @@
+/* float.h for target with IEEE 32 bit and 64 bit floating point formats */
+#ifndef _FLOAT_H_
+#define _FLOAT_H_
+/* Produced by enquire version 4.3, CWI, Amsterdam */
+
+ /* Radix of exponent representation */
+#undef FLT_RADIX
+#define FLT_RADIX 2
+ /* Number of base-FLT_RADIX digits in the significand of a float */
+#undef FLT_MANT_DIG
+#define FLT_MANT_DIG 24
+ /* Number of decimal digits of precision in a float */
+#undef FLT_DIG
+#define FLT_DIG 6
+ /* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown */
+#undef FLT_ROUNDS
+#define FLT_ROUNDS 1
+ /* Difference between 1.0 and the minimum float greater than 1.0 */
+#undef FLT_EPSILON
+#define FLT_EPSILON 1.19209290e-07F
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */
+#undef FLT_MIN_EXP
+#define FLT_MIN_EXP (-125)
+ /* Minimum normalised float */
+#undef FLT_MIN
+#define FLT_MIN 1.17549435e-38F
+ /* Minimum int x such that 10**x is a normalised float */
+#undef FLT_MIN_10_EXP
+#define FLT_MIN_10_EXP (-37)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable float */
+#undef FLT_MAX_EXP
+#define FLT_MAX_EXP 128
+ /* Maximum float */
+#undef FLT_MAX
+#define FLT_MAX 3.40282347e+38F
+ /* Maximum int x such that 10**x is a representable float */
+#undef FLT_MAX_10_EXP
+#define FLT_MAX_10_EXP 38
+
+ /* Number of base-FLT_RADIX digits in the significand of a double */
+#undef DBL_MANT_DIG
+#define DBL_MANT_DIG 53
+ /* Number of decimal digits of precision in a double */
+#undef DBL_DIG
+#define DBL_DIG 15
+ /* Difference between 1.0 and the minimum double greater than 1.0 */
+#undef DBL_EPSILON
+#define DBL_EPSILON 2.2204460492503131e-16
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */
+#undef DBL_MIN_EXP
+#define DBL_MIN_EXP (-1021)
+ /* Minimum normalised double */
+#undef DBL_MIN
+#define DBL_MIN 2.2250738585072014e-308
+ /* Minimum int x such that 10**x is a normalised double */
+#undef DBL_MIN_10_EXP
+#define DBL_MIN_10_EXP (-307)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable double */
+#undef DBL_MAX_EXP
+#define DBL_MAX_EXP 1024
+ /* Maximum double */
+#undef DBL_MAX
+#define DBL_MAX 1.7976931348623157e+308
+ /* Maximum int x such that 10**x is a representable double */
+#undef DBL_MAX_10_EXP
+#define DBL_MAX_10_EXP 308
+
+ /* Number of base-FLT_RADIX digits in the significand of a long double */
+#undef LDBL_MANT_DIG
+#define LDBL_MANT_DIG 53
+ /* Number of decimal digits of precision in a long double */
+#undef LDBL_DIG
+#define LDBL_DIG 15
+ /* Difference between 1.0 and the minimum long double greater than 1.0 */
+#undef LDBL_EPSILON
+#define LDBL_EPSILON 2.2204460492503131e-16L
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised long double */
+#undef LDBL_MIN_EXP
+#define LDBL_MIN_EXP (-1021)
+ /* Minimum normalised long double */
+#undef LDBL_MIN
+#define LDBL_MIN 2.2250738585072014e-308L
+ /* Minimum int x such that 10**x is a normalised long double */
+#undef LDBL_MIN_10_EXP
+#define LDBL_MIN_10_EXP (-307)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable long double */
+#undef LDBL_MAX_EXP
+#define LDBL_MAX_EXP 1024
+ /* Maximum long double */
+#undef LDBL_MAX
+#define LDBL_MAX 1.7976931348623157e+308L
+ /* Maximum int x such that 10**x is a representable long double */
+#undef LDBL_MAX_10_EXP
+#define LDBL_MAX_10_EXP 308
+
+#endif /* _FLOAT_H_ */
diff --git a/gnu/usr.bin/gcc/config/float-sh.h b/gnu/usr.bin/gcc/config/float-sh.h
new file mode 100644
index 00000000000..9a942987920
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/float-sh.h
@@ -0,0 +1,130 @@
+/* float.h for target sh3e with optional IEEE 32 bit double format */
+#ifndef _FLOAT_H_
+#define _FLOAT_H_
+/* Produced by enquire version 4.3, CWI, Amsterdam */
+
+ /* Radix of exponent representation */
+#undef FLT_RADIX
+#define FLT_RADIX 2
+ /* Number of base-FLT_RADIX digits in the significand of a float */
+#undef FLT_MANT_DIG
+#define FLT_MANT_DIG 24
+ /* Number of decimal digits of precision in a float */
+#undef FLT_DIG
+#define FLT_DIG 6
+ /* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown */
+#undef FLT_ROUNDS
+#define FLT_ROUNDS 1
+ /* Difference between 1.0 and the minimum float greater than 1.0 */
+#undef FLT_EPSILON
+#define FLT_EPSILON 1.19209290e-07F
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */
+#undef FLT_MIN_EXP
+#define FLT_MIN_EXP (-125)
+ /* Minimum normalised float */
+#undef FLT_MIN
+#define FLT_MIN 1.17549435e-38F
+ /* Minimum int x such that 10**x is a normalised float */
+#undef FLT_MIN_10_EXP
+#define FLT_MIN_10_EXP (-37)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable float */
+#undef FLT_MAX_EXP
+#define FLT_MAX_EXP 128
+ /* Maximum float */
+#undef FLT_MAX
+#define FLT_MAX 3.40282347e+38F
+ /* Maximum int x such that 10**x is a representable float */
+#undef FLT_MAX_10_EXP
+#define FLT_MAX_10_EXP 38
+
+#ifdef __SH3E__
+
+ /* Number of base-FLT_RADIX digits in the significand of a double */
+#undef DBL_MANT_DIG
+#define DBL_MANT_DIG 24
+ /* Number of decimal digits of precision in a double */
+#undef DBL_DIG
+#define DBL_DIG 6
+ /* Difference between 1.0 and the minimum double greater than 1.0 */
+#undef DBL_EPSILON
+#define DBL_EPSILON 1.19209290e-07F
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */
+#undef DBL_MIN_EXP
+#define DBL_MIN_EXP (-125)
+ /* Minimum normalised double */
+#undef DBL_MIN
+#define DBL_MIN 1.17549435e-38F
+ /* Minimum int x such that 10**x is a normalised double */
+#undef DBL_MIN_10_EXP
+#define DBL_MIN_10_EXP (-37)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable double */
+#undef DBL_MAX_EXP
+#define DBL_MAX_EXP 128
+ /* Maximum double */
+#undef DBL_MAX
+#define DBL_MAX 3.40282347e+38F
+ /* Maximum int x such that 10**x is a representable double */
+#undef DBL_MAX_10_EXP
+#define DBL_MAX_10_EXP 38
+
+#else
+
+ /* Number of base-FLT_RADIX digits in the significand of a double */
+#undef DBL_MANT_DIG
+#define DBL_MANT_DIG 53
+ /* Number of decimal digits of precision in a double */
+#undef DBL_DIG
+#define DBL_DIG 15
+ /* Difference between 1.0 and the minimum double greater than 1.0 */
+#undef DBL_EPSILON
+#define DBL_EPSILON 2.2204460492503131e-16
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */
+#undef DBL_MIN_EXP
+#define DBL_MIN_EXP (-1021)
+ /* Minimum normalised double */
+#undef DBL_MIN
+#define DBL_MIN 2.2250738585072014e-308
+ /* Minimum int x such that 10**x is a normalised double */
+#undef DBL_MIN_10_EXP
+#define DBL_MIN_10_EXP (-307)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable double */
+#undef DBL_MAX_EXP
+#define DBL_MAX_EXP 1024
+ /* Maximum double */
+#undef DBL_MAX
+#define DBL_MAX 1.7976931348623157e+308
+ /* Maximum int x such that 10**x is a representable double */
+#undef DBL_MAX_10_EXP
+#define DBL_MAX_10_EXP 308
+
+#endif
+
+ /* Number of base-FLT_RADIX digits in the significand of a long double */
+#undef LDBL_MANT_DIG
+#define LDBL_MANT_DIG 53
+ /* Number of decimal digits of precision in a long double */
+#undef LDBL_DIG
+#define LDBL_DIG 15
+ /* Difference between 1.0 and the minimum long double greater than 1.0 */
+#undef LDBL_EPSILON
+#define LDBL_EPSILON 2.2204460492503131e-16
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised long double */
+#undef LDBL_MIN_EXP
+#define LDBL_MIN_EXP (-1021)
+ /* Minimum normalised long double */
+#undef LDBL_MIN
+#define LDBL_MIN 2.2250738585072014e-308
+ /* Minimum int x such that 10**x is a normalised long double */
+#undef LDBL_MIN_10_EXP
+#define LDBL_MIN_10_EXP (-307)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable long double */
+#undef LDBL_MAX_EXP
+#define LDBL_MAX_EXP 1024
+ /* Maximum long double */
+#undef LDBL_MAX
+#define LDBL_MAX 1.7976931348623157e+308
+ /* Maximum int x such that 10**x is a representable long double */
+#undef LDBL_MAX_10_EXP
+#define LDBL_MAX_10_EXP 308
+
+#endif /* _FLOAT_H_ */
diff --git a/gnu/usr.bin/gcc/config/float-vax.h b/gnu/usr.bin/gcc/config/float-vax.h
new file mode 100644
index 00000000000..3c87f795ef2
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/float-vax.h
@@ -0,0 +1,96 @@
+/* float.h for target with VAX floating point formats */
+#ifndef _FLOAT_H_
+#define _FLOAT_H_
+/* Produced by enquire version 4.3, CWI, Amsterdam */
+
+ /* Radix of exponent representation */
+#undef FLT_RADIX
+#define FLT_RADIX 2
+ /* Number of base-FLT_RADIX digits in the significand of a float */
+#undef FLT_MANT_DIG
+#define FLT_MANT_DIG 24
+ /* Number of decimal digits of precision in a float */
+#undef FLT_DIG
+#define FLT_DIG 6
+ /* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown */
+#undef FLT_ROUNDS
+#define FLT_ROUNDS 1
+ /* Difference between 1.0 and the minimum float greater than 1.0 */
+#undef FLT_EPSILON
+#define FLT_EPSILON 1.19209290e-07F
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */
+#undef FLT_MIN_EXP
+#define FLT_MIN_EXP (-127)
+ /* Minimum normalised float */
+#undef FLT_MIN
+#define FLT_MIN 2.93873588e-39F
+ /* Minimum int x such that 10**x is a normalised float */
+#undef FLT_MIN_10_EXP
+#define FLT_MIN_10_EXP (-38)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable float */
+#undef FLT_MAX_EXP
+#define FLT_MAX_EXP 127
+ /* Maximum float */
+#undef FLT_MAX
+#define FLT_MAX 1.70141173e+38F
+ /* Maximum int x such that 10**x is a representable float */
+#undef FLT_MAX_10_EXP
+#define FLT_MAX_10_EXP 38
+
+ /* Number of base-FLT_RADIX digits in the significand of a double */
+#undef DBL_MANT_DIG
+#define DBL_MANT_DIG 56
+ /* Number of decimal digits of precision in a double */
+#undef DBL_DIG
+#define DBL_DIG 16
+ /* Difference between 1.0 and the minimum double greater than 1.0 */
+#undef DBL_EPSILON
+#define DBL_EPSILON 2.77555756156289135e-17
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */
+#undef DBL_MIN_EXP
+#define DBL_MIN_EXP (-127)
+ /* Minimum normalised double */
+#undef DBL_MIN
+#define DBL_MIN 2.93873587705571877e-39
+ /* Minimum int x such that 10**x is a normalised double */
+#undef DBL_MIN_10_EXP
+#define DBL_MIN_10_EXP (-38)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable double */
+#undef DBL_MAX_EXP
+#define DBL_MAX_EXP 127
+ /* Maximum double */
+#undef DBL_MAX
+#define DBL_MAX 1.70141183460469229e+38
+ /* Maximum int x such that 10**x is a representable double */
+#undef DBL_MAX_10_EXP
+#define DBL_MAX_10_EXP 38
+
+ /* Number of base-FLT_RADIX digits in the significand of a long double */
+#undef LDBL_MANT_DIG
+#define LDBL_MANT_DIG 56
+ /* Number of decimal digits of precision in a long double */
+#undef LDBL_DIG
+#define LDBL_DIG 16
+ /* Difference between 1.0 and the minimum long double greater than 1.0 */
+#undef LDBL_EPSILON
+#define LDBL_EPSILON 2.77555756156289135e-17
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised long double */
+#undef LDBL_MIN_EXP
+#define LDBL_MIN_EXP (-127)
+ /* Minimum normalised long double */
+#undef LDBL_MIN
+#define LDBL_MIN 2.93873587705571877e-39
+ /* Minimum int x such that 10**x is a normalised long double */
+#undef LDBL_MIN_10_EXP
+#define LDBL_MIN_10_EXP (-38)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable long double */
+#undef LDBL_MAX_EXP
+#define LDBL_MAX_EXP 127
+ /* Maximum long double */
+#undef LDBL_MAX
+#define LDBL_MAX 1.70141183460469229e+38
+ /* Maximum int x such that 10**x is a representable long double */
+#undef LDBL_MAX_10_EXP
+#define LDBL_MAX_10_EXP 38
+
+#endif /* _FLOAT_H_ */
diff --git a/gnu/usr.bin/gcc/config/i370/i370.c b/gnu/usr.bin/gcc/config/i370/i370.c
new file mode 100644
index 00000000000..55189825540
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i370/i370.c
@@ -0,0 +1,584 @@
+/* Subroutines for insn-output.c for System/370.
+ Copyright (C) 1989, 1993, 1995, 1997 Free Software Foundation, Inc.
+ Contributed by Jan Stein (jan@cd.chalmers.se).
+ Modified for MVS C/370 by Dave Pitts (dpitts@nyx.cs.du.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 <string.h>
+#include <ctype.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 "flags.h"
+#include "recog.h"
+#ifdef sun
+#include <sys/types.h>
+#include <ctype.h>
+#endif
+#include <time.h>
+
+
+/* Label node, this structure is used to keep track of labels on the
+ current page. */
+typedef struct label_node
+ {
+ struct label_node *label_next;
+ int label_id;
+ int label_page;
+ }
+label_node_t;
+
+/* Is 1 when a label has been generated and the base register must be
+ reloaded. */
+int mvs_label_emitted = 0;
+
+/* Current function starting base page. */
+int function_base_page;
+
+/* Length of the current page code. */
+int mvs_page_code;
+
+/* Length of the current page literals. */
+int mvs_page_lit;
+
+/* Current function name. */
+char *mvs_function_name = 0;
+
+/* Current function name length. */
+int mvs_function_name_length = 0;
+
+/* Page number for multi-page functions. */
+int mvs_page_num = 0;
+
+/* Label node list anchor. */
+static label_node_t *label_anchor = 0;
+
+/* Label node free list anchor. */
+static label_node_t *free_anchor = 0;
+
+/* Assembler source file descriptor. */
+static FILE *assembler_source = 0;
+
+/* Define the length of the internal MVS function table. */
+#define MVS_FUNCTION_TABLE_LENGTH 32
+
+/* C/370 internal function table. These functions use non-standard linkage
+ and must handled in a special manner. */
+static char *mvs_function_table[MVS_FUNCTION_TABLE_LENGTH] =
+{
+ "ceil", "edc_acos", "edc_asin", "edc_ata2", "edc_atan", "edc_cos",
+ "edc_cosh", "edc_erf", "edc_erfc", "edc_exp", "edc_gamm", "edc_lg10",
+ "edc_log", "edc_sin", "edc_sinh", "edc_sqrt", "edc_tan", "edc_tanh",
+ "fabs", "floor", "fmod", "frexp", "hypot", "j0",
+ "j1", "jn", "ldexp", "modf", "pow", "y0",
+ "y1", "yn"
+};
+
+/* ASCII to EBCDIC conversion table. */
+#if defined(TARGET_EBCDIC) && !defined(HOST_EBCDIC)
+static unsigned char ascebc[256] =
+{
+ /*00 NL SH SX EX ET NQ AK BL */
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
+ /*08 BS HT LF VT FF CR SO SI */
+ 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ /*10 DL D1 D2 D3 D4 NK SN EB */
+ 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
+ /*18 CN EM SB EC FS GS RS US */
+ 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
+ /*20 SP ! " # $ % & ' */
+ 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
+ /*28 ( ) * + , - . / */
+ 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+ /*30 0 1 2 3 4 5 6 7 */
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ /*38 8 9 : ; < = > ? */
+ 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
+ /*40 @ A B C D E F G */
+ 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ /*48 H I J K L M N O */
+ 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+ /*50 P Q R S T U V W */
+ 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+ /*58 X Y Z [ \ ] ^ _ */
+ 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
+ /*60 ` a b c d e f g */
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ /*68 h i j k l m n o */
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ /*70 p q r s t u v w */
+ 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+ /*78 x y z { | } ~ DL */
+ 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
+};
+#endif
+
+/* EBCDIC to ASCII conversion table. */
+#if defined(HOST_EBCDIC) && !defined(TARGET_EBCDIC)
+unsigned char ebcasc[256] =
+{
+ /*00 NU SH SX EX PF HT LC DL */
+ 0x00, 0x01, 0x02, 0x03, 0x00, 0x09, 0x00, 0x7F,
+ /*08 SM VT FF CR SO SI */
+ 0x00, 0x00, 0x00, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ /*10 DE D1 D2 TM RS NL BS IL */
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x0A, 0x08, 0x00,
+ /*18 CN EM CC C1 FS GS RS US */
+ 0x18, 0x19, 0x00, 0x00, 0x1C, 0x1D, 0x1E, 0x1F,
+ /*20 DS SS FS BP LF EB EC */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x17, 0x1B,
+ /*28 SM C2 EQ AK BL */
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07, 0x00,
+ /*30 SY PN RS UC ET */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ /*38 C3 D4 NK SU */
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x00, 0x1A,
+ /*40 SP */
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*48 . < ( + | */
+ 0x00, 0x00, 0x00, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
+ /*50 & */
+ 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*58 ! $ * ) ; ^ */
+ 0x00, 0x00, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
+ /*60 - / */
+ 0x2D, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*68 , % _ > ? */
+ 0x00, 0x00, 0x00, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
+ /*70 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*78 ` : # @ ' = " */
+ 0x00, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
+ /*80 a b c d e f g */
+ 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ /*88 h i { */
+ 0x68, 0x69, 0x00, 0x7B, 0x00, 0x00, 0x00, 0x00,
+ /*90 j k l m n o p */
+ 0x00, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
+ /*98 q r } */
+ 0x71, 0x72, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x00,
+ /*A0 ~ s t u v w x */
+ 0x00, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ /*A8 y z [ */
+ 0x79, 0x7A, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00,
+ /*B0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*B8 ] */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00,
+ /*C0 { A B C D E F G */
+ 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ /*C8 H I */
+ 0x48, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*D0 } J K L M N O P */
+ 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
+ /*D8 Q R */
+ 0x51, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*E0 \ S T U V W X */
+ 0x5C, 0x00, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ /*E8 Y Z */
+ 0x59, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*F0 0 1 2 3 4 5 6 7 */
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ /*F8 8 9 */
+ 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF
+};
+#endif
+
+/* Map characters from one character set to another.
+ C is the character to be translated. */
+
+char
+mvs_map_char (c)
+ char c;
+{
+#if defined(TARGET_EBCDIC) && !defined(HOST_EBCDIC)
+ return ascebc[c];
+#else
+#if defined(HOST_EBCDIC) && !defined(TARGET_EBCDIC)
+ return ebcasc[c];
+#else
+ return c;
+#endif
+#endif
+}
+
+/* Emit reload of base register if indicated. This is to eliminate multiple
+ reloads when several labels are generated pointing to the same place
+ in the code. */
+
+int
+check_label_emit (void)
+{
+ if (mvs_label_emitted)
+ {
+ mvs_label_emitted = 0;
+ mvs_page_code += 4;
+ fprintf (assembler_source, "\tL\t%d,%d(,%d)\n",
+ BASE_REGISTER, (mvs_page_num - function_base_page) * 4,
+ PAGE_REGISTER);
+ }
+}
+
+/* Add the label to the current page label list. If a free element is available
+ it will be used for the new label. Otherwise, a label element will be
+ allocated from memory.
+ ID is the label number of the label being added to the list. */
+
+int
+mvs_add_label (id)
+ int id;
+{
+ label_node_t *lp;
+
+ if (free_anchor)
+ {
+ lp = free_anchor;
+ free_anchor = lp->label_next;
+ }
+ else
+ {
+ lp = (label_node_t *) malloc (sizeof (label_node_t));
+ if (lp == 0)
+ {
+ fatal ("virtual memory exhausted\n");
+ abort ();
+ }
+ }
+ lp->label_id = id;
+ lp->label_page = mvs_page_num;
+ lp->label_next = label_anchor;
+ label_anchor = lp;
+}
+
+/* Check to see if the label is in the list. If 1 is returned then a load
+ and branch on register must be generated.
+ ID is the label number of the label being checked. */
+
+int
+mvs_check_label (id)
+ int id;
+{
+ label_node_t *lp;
+
+ for (lp = label_anchor; lp; lp = lp->label_next)
+ {
+ if (lp->label_id == id)
+ return 1;
+ }
+ return 0;
+}
+
+/* The label list for the current page freed by linking the list onto the free
+ label element chain. */
+
+int
+mvs_free_label (void)
+{
+ if (label_anchor)
+ {
+ if (free_anchor)
+ label_anchor->label_next = free_anchor;
+ free_anchor = label_anchor;
+ }
+ label_anchor = 0;
+}
+
+/* If the page size limit is reached a new code page is started, and the base
+ register is set to it. This page break point is counted conservatively,
+ most literals that have the same value are collapsed by the assembler.
+ True is returned when a new page is started.
+ FILE is the assembler output file descriptor.
+ CODE is the length, in bytes, of the instruction to be emitted.
+ LIT is the length of the literal to be emitted. */
+
+int
+mvs_check_page (file, code, lit)
+ FILE *file;
+ int code, lit;
+{
+ if (file)
+ assembler_source = file;
+
+ if (mvs_page_code + code + mvs_page_lit + lit > MAX_MVS_PAGE_LENGTH)
+ {
+ fprintf (assembler_source, "\tB\tPGE%d\n", mvs_page_num);
+ fprintf (assembler_source, "\tDS\t0F\n");
+ fprintf (assembler_source, "\tLTORG\n");
+ fprintf (assembler_source, "\tDS\t0F\n");
+ fprintf (assembler_source, "PGE%d\tEQU\t*\n", mvs_page_num);
+ fprintf (assembler_source, "\tDROP\t%d\n", BASE_REGISTER);
+ mvs_page_num++;
+ fprintf (assembler_source, "\tBALR\t%d,0\n", BASE_REGISTER);
+ fprintf (assembler_source, "PG%d\tEQU\t*\n", mvs_page_num);
+ fprintf (assembler_source, "\tUSING\t*,%d\n", BASE_REGISTER);
+ mvs_free_label ();
+ mvs_page_code = code;
+ mvs_page_lit = lit;
+ return 1;
+ }
+ mvs_page_code += code;
+ mvs_page_lit += lit;
+ return 0;
+}
+
+/* Check for C/370 runtime function, they don't use standard calling
+ conventions. True is returned if the function is in the table.
+ NAME is the name of the current function. */
+
+int
+mvs_function_check (name)
+ char *name;
+{
+ int lower, middle, upper;
+ int i;
+
+ lower = 0;
+ upper = MVS_FUNCTION_TABLE_LENGTH - 1;
+ while (lower <= upper)
+ {
+ middle = (lower + upper) / 2;
+ i = strcmp (name, mvs_function_table[middle]);
+ if (i == 0)
+ return 1;
+ if (i < 0)
+ upper = middle - 1;
+ else
+ lower = middle + 1;
+ }
+ return 0;
+}
+
+
+/* Return 1 if OP is a valid S operand for an RS, SI or SS type instruction.
+ OP is the current operation.
+ MODE is the current operation mode. */
+
+int
+s_operand (op, mode)
+ register rtx op;
+ enum machine_mode mode;
+{
+ extern int volatile_ok;
+ register enum rtx_code code = GET_CODE (op);
+
+ if (CONSTANT_ADDRESS_P (op))
+ return 1;
+ if (mode == VOIDmode || GET_MODE (op) != mode)
+ return 0;
+ if (code == MEM)
+ {
+ register rtx x = XEXP (op, 0);
+
+ if (!volatile_ok && op->volatil)
+ return 0;
+ if (REG_P (x) && REG_OK_FOR_BASE_P (x))
+ return 1;
+ if (GET_CODE (x) == PLUS
+ && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0))
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (unsigned) INTVAL (XEXP (x, 1)) < 4096)
+ return 1;
+ }
+ return 0;
+}
+
+
+/* Return 1 if OP is a valid R or S operand for an RS, SI or SS type
+ instruction.
+ OP is the current operation.
+ MODE is the current operation mode. */
+
+int
+r_or_s_operand (op, mode)
+ register rtx op;
+ enum machine_mode mode;
+{
+ extern int volatile_ok;
+ register enum rtx_code code = GET_CODE (op);
+
+ if (CONSTANT_ADDRESS_P (op))
+ return 1;
+ if (mode == VOIDmode || GET_MODE (op) != mode)
+ return 0;
+ if (code == REG)
+ return 1;
+ else if (code == MEM)
+ {
+ register rtx x = XEXP (op, 0);
+
+ if (!volatile_ok && op->volatil)
+ return 0;
+ if (REG_P (x) && REG_OK_FOR_BASE_P (x))
+ return 1;
+ if (GET_CODE (x) == PLUS
+ && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0))
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (unsigned) INTVAL (XEXP (x, 1)) < 4096)
+ return 1;
+ }
+ return 0;
+}
+
+
+/* Return 1 if the next instruction is an unsigned jump instruction.
+ INSN is the current instruction. */
+
+unsigned_jump_follows_p (insn)
+ register rtx insn;
+{
+ insn = NEXT_INSN (insn);
+ if (GET_CODE (insn) != JUMP_INSN)
+ return 0;
+
+ insn = XEXP (insn, 3);
+ if (GET_CODE (insn) != SET)
+ return 0;
+
+ if (GET_CODE (XEXP (insn, 0)) != PC)
+ return 0;
+
+ insn = XEXP (insn, 1);
+ if (GET_CODE (insn) != IF_THEN_ELSE)
+ return 0;
+
+ insn = XEXP (insn, 0);
+ return GET_CODE (insn) != GE && GET_CODE (insn) != GT
+ && GET_CODE (insn) != LE && GET_CODE (insn) != LT;
+}
+
+void
+i370_function_prolog (f, l)
+ FILE *f;
+ int l;
+{
+#if MACROPROLOGUE == 1
+ fprintf (f, "\tEDCPRLG USRDSAL=%d,BASEREG=%d\n",
+ STACK_POINTER_OFFSET + l - 120 +
+ current_function_outgoing_args_size, BASE_REGISTER);
+ fprintf (f, "PG%d\tEQU\t*\n", mvs_page_num );
+ fprintf (f, "\tLR\t11,1\n");
+ fprintf (f, "\tL\t%d,=A(PGT%d)\n", PAGE_REGISTER, mvs_page_num);
+ mvs_page_code = 6;
+ mvs_page_lit = 4;
+ mvs_check_page (f, 0, 0);
+ function_base_page = mvs_page_num;
+#else /* MACROPROLOGUE != 1 */
+ static int function_label_index = 1;
+ static int function_first = 0;
+ static int function_year, function_month, function_day;
+ static int function_hour, function_minute, function_second;
+ int i;
+ if (!function_first)
+ {
+ struct tm *function_time;
+ time_t lcltime;
+ time (&lcltime);
+ function_time = localtime (&lcltime);
+ function_year = function_time->tm_year + 1900;
+ function_month = function_time->tm_mon + 1;
+ function_day = function_time->tm_mday;
+ function_hour = function_time->tm_hour;
+ function_minute = function_time->tm_min;
+ function_second = function_time->tm_sec;
+ fprintf (f, "PPA2\tDS\t0F\n");
+ fprintf (f, "\tDC\tX'03',X'00',X'33',X'00'\n");
+ fprintf (f, "\tDC\tV(CEESTART),A(0)\n");
+ fprintf (f, "\tDC\tA(CEETIMES)\n");
+ fprintf (f, "CEETIMES\tDS\t0F\n");
+ fprintf (f, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n",
+ function_year, function_month, function_day,
+ function_hour, function_minute, function_second);
+ fprintf (f, "\tDC\tCL2'01',CL4'0100'\n");
+ }
+ fprintf (f, "$DSD%03d\tDSECT\n", function_label_index);
+ fprintf (f, "\tDS\tD\n");
+ fprintf (f, "\tDS\tCL(%d)\n", STACK_POINTER_OFFSET + l
+ + current_function_outgoing_args_size);
+ fprintf (f, "\tORG\t$DSD%03d\n", function_label_index);
+ fprintf (f, "\tDS\tCL(120+8)\n");
+ fprintf (f, "\tORG\n");
+ fprintf (f, "\tDS\t0D\n");
+ fprintf (f, "$DSL%03d\tEQU\t*-$DSD%03d-8\n", function_label_index,
+ function_label_index);
+ fprintf (f, "\tDS\t0H\n");
+ assemble_name (f, mvs_function_name);
+ fprintf (f, "\tEQU\t*\n");
+ fprintf (f, "\tUSING\t*,15\n");
+ fprintf (f, "\tB\tFPL%03d\n", function_label_index);
+ fprintf (f, "\tDC\tAL1(FPL%03d+4-*)\n", function_label_index + 1);
+ fprintf (f, "\tDC\tX'CE',X'A0',AL1(16)\n");
+ fprintf (f, "\tDC\tAL4(PPA2)\n");
+ fprintf (f, "\tDC\tAL4(0)\n");
+ fprintf (f, "\tDC\tAL4($DSL%03d)\n", function_label_index);
+ fprintf (f, "FPL%03d\tEQU\t*\n", function_label_index + 1);
+ fprintf (f, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name),
+ mvs_function_name);
+ fprintf (f, "FPL%03d\tDS\t0H\n", function_label_index);
+ fprintf (f, "\tSTM\t14,12,12(13)\n");
+ fprintf (f, "\tL\t2,76(,13)\n");
+ fprintf (f, "\tL\t0,16(,15)\n");
+ fprintf (f, "\tALR\t0,2\n");
+ fprintf (f, "\tCL\t0,12(,12)\n");
+ fprintf (f, "\tBNH\t*+10\n");
+ fprintf (f, "\tL\t15,116(,12)\n");
+ fprintf (f, "\tBALR\t14,15\n");
+ fprintf (f, "\tL\t15,72(,13)\n");
+ fprintf (f, "\tSTM\t15,0,72(2)\n");
+ fprintf (f, "\tMVI\t0(2),X'10'\n");
+ fprintf (f, "\tST\t2,8(,13)\n ");
+ fprintf (f, "\tST\t13,4(,2)\n ");
+ fprintf (f, "\tLR\t13,2\n");
+ fprintf (f, "\tDROP\t15\n");
+ fprintf (f, "\tBALR\t%d,0\n", BASE_REGISTER);
+ fprintf (f, "PG%d\tEQU\t*\n", mvs_page_num );
+ fprintf (f, "\tUSING\t*,%d\n", BASE_REGISTER);
+ fprintf (f, "\tLR\t11,1\n");
+ fprintf (f, "\tL\t%d,=A(PGT%d)\n", PAGE_REGISTER, mvs_page_num);
+ mvs_page_code = 4;
+ mvs_page_lit = 4;
+ mvs_check_page (f, 0, 0);
+ function_base_page = mvs_page_num;
+ function_first = 1;
+ function_label_index += 2;
+#endif /* MACROPROLOGUE */
+}
diff --git a/gnu/usr.bin/gcc/config/i370/i370.h b/gnu/usr.bin/gcc/config/i370/i370.h
new file mode 100644
index 00000000000..e213883075b
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i370/i370.h
@@ -0,0 +1,1441 @@
+/* Definitions of target machine for GNU compiler. System/370 version.
+ Copyright (C) 1989, 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Jan Stein (jan@cd.chalmers.se).
+ Modified for C/370 MVS by Dave Pitts (dpitts@nyx.cs.du.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_VERSION printf (" (370/MVS)");
+
+/* Options for the preprocessor for this target machine. */
+
+#define CPP_SPEC "-trigraphs"
+
+/* Names to predefine in the preprocessor for this target machine. */
+
+#define CPP_PREDEFINES "-DGCC -Dgcc -DMVS -Dmvs -Asystem(mvs) -Acpu(i370) -Amachine(i370)"
+
+/* Run-time compilation parameters selecting different hardware subsets. */
+
+extern int target_flags;
+
+/* The sizes of the code and literals on the current page. */
+
+extern int mvs_page_code, mvs_page_lit;
+
+/* The current page number and the base page number for the function. */
+
+extern int mvs_page_num, function_base_page;
+
+/* True if a label has been emitted. */
+
+extern int mvs_label_emitted;
+
+/* The name of the current function. */
+
+extern char *mvs_function_name;
+
+/* The length of the function name malloc'd area. */
+
+extern int mvs_function_name_length;
+
+/* The amount of space used for outgoing arguments. */
+
+extern int current_function_outgoing_args_size;
+
+/* Compile using char instructions (mvc, nc, oc, xc). On 4341 use this since
+ these are more than twice as fast as load-op-store.
+ On 3090 don't use this since load-op-store is much faster. */
+
+#define TARGET_CHAR_INSTRUCTIONS (target_flags & 1)
+
+/* Default target switches */
+
+#define TARGET_DEFAULT 1
+
+/* Macro to define tables used to set the flags. This is a list in braces
+ of pairs in braces, each pair being { "NAME", VALUE }
+ where VALUE is the bits to set or minus the bits to clear.
+ An empty string NAME is used to identify the default VALUE. */
+
+#define TARGET_SWITCHES \
+{ { "char-instructions", 1}, \
+ { "no-char-instructions", -1}, \
+ { "", TARGET_DEFAULT} }
+
+/* To use IBM supplied macro function prologue and epilogue, define the
+ following to 1. Should only be needed if IBM changes the definition
+ of their prologue and epilogue. */
+
+#define MACROPROLOGUE 0
+#define MACROEPILOGUE 0
+
+/* Target machine storage layout */
+
+/* Define this if most significant bit is lowest numbered in instructions
+ that operate on numbered bit-fields. */
+
+#define BITS_BIG_ENDIAN 1
+
+/* Define this if most significant byte of a word is the lowest numbered. */
+
+#define BYTES_BIG_ENDIAN 1
+
+/* Define this if MS word of a multiword is the lowest numbered. */
+
+#define WORDS_BIG_ENDIAN 1
+
+/* 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. */
+
+#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 pointers in memory. */
+
+#define POINTER_BOUNDARY 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. */
+
+#define FUNCTION_BOUNDARY 32
+
+/* There is no point aligning anything to a rounder boundary than this. */
+
+#define BIGGEST_ALIGNMENT 64
+
+/* Alignment of field after `int : 0' in a structure. */
+
+#define EMPTY_FIELD_BOUNDARY 32
+
+/* Define this if move instructions will actually fail to work when given
+ unaligned data. */
+
+#define STRICT_ALIGNMENT 0
+
+/* Define target floating point format. */
+
+#define TARGET_FLOAT_FORMAT IBM_FLOAT_FORMAT
+
+/* Define character mapping for cross-compiling. */
+
+#define TARGET_EBCDIC 1
+
+#ifdef HOST_EBCDIC
+#define MAP_CHARACTER(c) ((char)(c))
+#else
+#define MAP_CHARACTER(c) ((char)mvs_map_char (c))
+#endif
+
+/* Define maximum length of page minus page escape overhead. */
+
+#define MAX_MVS_PAGE_LENGTH 4080
+
+/* Define if special allocation order desired. */
+
+#define REG_ALLOC_ORDER \
+{ 0, 1, 2, 3, 14, 15, 12, 10, 9, 8, 7, 6, 5, 4, 16, 17, 18, 19, 11, 13 }
+
+/* Standard register usage. */
+
+/* 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.
+ For the 370, we give the data registers numbers 0-15,
+ and the floating point registers numbers 16-19. */
+
+#define FIRST_PSEUDO_REGISTER 20
+
+/* Define base and page registers. */
+
+#define BASE_REGISTER 3
+#define PAGE_REGISTER 4
+
+/* 1 for registers that have pervasive standard uses and are not available
+ for the register allocator. On the 370 under C/370, R13 is stack (DSA)
+ pointer, R12 is the TCA pointer, R3 is the base register, R4 is the page
+ origin table pointer and R11 is the arg pointer. */
+
+#define FIXED_REGISTERS \
+{ 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 }
+/*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19*/
+
+/* 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.
+ NOTE: all floating registers are undefined across calls. */
+
+#define CALL_USED_REGISTERS \
+{ 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
+/*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19*/
+
+/* 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. */
+
+#define HARD_REGNO_NREGS(REGNO, MODE) \
+ ((REGNO) > 15 ? 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 370, the cpu registers can hold QI, HI, SI, SF and DF. The
+ even registers can hold DI. The floating point registers can hold
+ either SF or DF. */
+
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+ ((REGNO) < 16 ? ((REGNO) & 1) == 0 || (MODE) != DImode \
+ : (MODE) == SFmode || (MODE) == DFmode)
+
+/* 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) == SFmode || (MODE1) == DFmode) \
+ == ((MODE2) == SFmode || (MODE2) == DFmode))
+
+/* Mark external references. */
+
+#define ENCODE_SECTION_INFO(decl) \
+ if (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)) \
+ SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
+
+/* Specify the registers used for certain standard purposes.
+ The values of these macros are register numbers. */
+
+/* 370 PC isn't overloaded on a register. */
+
+/* #define PC_REGNUM */
+
+/* Register to use for pushing function arguments. */
+
+#define STACK_POINTER_REGNUM 13
+
+/* Base register for access to local variables of the function. */
+
+#define FRAME_POINTER_REGNUM 13
+
+/* 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 1
+
+/* Base register for access to arguments of the function. */
+
+#define ARG_POINTER_REGNUM 11
+
+/* Register in which static-chain is passed to a function. */
+
+#define STATIC_CHAIN_REGNUM 10
+
+/* Register in which address to store a structure value is passed to
+ a function. */
+
+#define STRUCT_VALUE_REGNUM 1
+
+/* 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. */
+
+enum reg_class
+ {
+ NO_REGS, ADDR_REGS, DATA_REGS,
+ FP_REGS, ALL_REGS, LIM_REG_CLASSES
+ };
+
+#define GENERAL_REGS DATA_REGS
+#define N_REG_CLASSES (int) LIM_REG_CLASSES
+
+/* Give names of register classes as strings for dump file. */
+
+#define REG_CLASS_NAMES \
+{ "NO_REGS", "ADDR_REGS", "DATA_REGS", "FP_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, 0x0fffe, 0x0ffff, 0xf0000, 0xfffff}
+
+/* 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) \
+ ((REGNO) >= 16 ? FP_REGS : (REGNO) != 0 ? ADDR_REGS : DATA_REGS)
+
+/* The class value for index registers, and the one for base regs. */
+
+#define INDEX_REG_CLASS ADDR_REGS
+#define BASE_REG_CLASS ADDR_REGS
+
+/* Get reg_class from a letter such as appears in the machine description. */
+
+#define REG_CLASS_FROM_LETTER(C) \
+ ((C) == 'a' ? ADDR_REGS : \
+ ((C) == 'd' ? DATA_REGS : \
+ ((C) == 'f' ? FP_REGS : 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. */
+
+#define CONST_OK_FOR_LETTER_P(VALUE, C) \
+ ((C) == 'I' ? (unsigned) (VALUE) < 256 : \
+ (C) == 'J' ? (unsigned) (VALUE) < 4096 : \
+ (C) == 'K' ? (VALUE) >= -32768 && (VALUE) < 32768 : 0)
+
+/* Similar, but for floating constants, and defining letters G and H.
+ Here VALUE is the CONST_DOUBLE rtx itself. */
+
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 1
+
+/* 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. */
+
+#define PREFERRED_RELOAD_CLASS(X, CLASS) \
+ (GET_CODE(X) == CONST_DOUBLE ? FP_REGS : \
+ GET_CODE(X) == CONST_INT ? DATA_REGS : \
+ GET_CODE(X) == LABEL_REF || \
+ GET_CODE(X) == SYMBOL_REF || \
+ GET_CODE(X) == CONST ? ADDR_REGS : (CLASS))
+
+/* Return the maximum number of consecutive registers needed to represent
+ mode MODE in a register of class CLASS. */
+
+#define CLASS_MAX_NREGS(CLASS, MODE) \
+ ((CLASS) == FP_REGS ? 1 : \
+ (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* 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 \
+ (STACK_POINTER_OFFSET + current_function_outgoing_args_size)
+
+#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = STARTING_FRAME_OFFSET
+
+/* If we generate an insn to push BYTES bytes, this says how many the stack
+ pointer really advances by. On the 370, we have no push instruction. */
+
+/* #define PUSH_ROUNDING(BYTES) */
+
+/* Accumulate the outgoing argument count so we can request the right
+ DSA size and determine stack offset. */
+
+#define ACCUMULATE_OUTGOING_ARGS
+
+/* Define offset from stack pointer, to location where a parm can be
+ pushed. */
+
+#define STACK_POINTER_OFFSET 148
+
+/* Offset of first parameter from the argument pointer register value. */
+
+#define FIRST_PARM_OFFSET(FNDECL) 0
+
+/* 1 if N is a possible register number for function argument passing.
+ On the 370, no registers are used in this way. */
+
+#define FUNCTION_ARG_REGNO_P(N) 0
+
+/* 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. */
+
+#define CUMULATIVE_ARGS int
+
+/* 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, INDIRECT) ((CUM) = 0)
+
+/* 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) \
+ ((CUM) += ((MODE) == DFmode || (MODE) == SFmode \
+ ? 256 \
+ : (MODE) != BLKmode \
+ ? (GET_MODE_SIZE (MODE) + 3) / 4 \
+ : (int_size_in_bytes (TYPE) + 3) / 4))
+
+/* 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. */
+
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0
+
+/* 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) 0
+
+/* Define if returning from a function call automatically pops the
+ arguments described by the number-of-args field in the call. */
+
+#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
+
+/* 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 15. */
+
+#define RET_REG(MODE) ((MODE) == DFmode || (MODE) == SFmode ? 16 : 15)
+
+/* On the 370 the return value is in R15 or R16. */
+
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+ gen_rtx(REG, TYPE_MODE (VALTYPE), RET_REG(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, RET_REG(MODE))
+
+/* 1 if N is a possible register number for a function value.
+ On the 370 under C/370, R15 and R16 are thus used. */
+
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == 15 || (N) == 16)
+
+/* This macro definition sets up a default value for `main' to return. */
+
+#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
+
+/* This macro generates the assembly code for function entry.
+ All of the C/370 environment is preserved. */
+#define FUNCTION_PROLOGUE(FILE, LSIZE) i370_function_prolog ((FILE), (LSIZE));
+
+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
+{ \
+ if (strlen (NAME) * 2 > mvs_function_name_length) \
+ { \
+ if (mvs_function_name) \
+ free (mvs_function_name); \
+ mvs_function_name = 0; \
+ } \
+ if (!mvs_function_name) \
+ { \
+ mvs_function_name_length = strlen (NAME) * 2; \
+ mvs_function_name = (char *) malloc (mvs_function_name_length); \
+ if (mvs_function_name == 0) \
+ { \
+ fatal ("virtual memory exceeded"); \
+ abort (); \
+ } \
+ } \
+ if (!strcmp (NAME, "main")) \
+ strcpy (mvs_function_name, "gccmain"); \
+ else \
+ strcpy (mvs_function_name, NAME); \
+}
+
+/* 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 MACROEPILOGUE == 1
+#define FUNCTION_EPILOGUE(FILE, LSIZE) \
+{ \
+ int i; \
+ check_label_emit(); \
+ mvs_check_page (FILE,14,0); \
+ fprintf (FILE, "\tEDCEPIL\n"); \
+ mvs_page_num++; \
+ fprintf (FILE, "\tDS\t0F\n" ); \
+ fprintf (FILE, "\tLTORG\n"); \
+ fprintf (FILE, "\tDS\t0F\n"); \
+ fprintf (FILE, "PGT%d\tEQU\t*\n", function_base_page); \
+ mvs_free_label(); \
+ for ( i = function_base_page; i < mvs_page_num; i++ ) \
+ fprintf (FILE, "\tDC\tA(PG%d)\n", i); \
+}
+#else /* MACROEPILOGUE != 1 */
+#define FUNCTION_EPILOGUE(FILE, LSIZE) \
+{ \
+ int i; \
+ check_label_emit(); \
+ mvs_check_page (FILE,14,0); \
+ fprintf (FILE, "\tL\t13,4(,13)\n"); \
+ fprintf (FILE, "\tL\t14,12(,13)\n"); \
+ fprintf (FILE, "\tLM\t2,12,28(13)\n"); \
+ fprintf (FILE, "\tBALR\t1,14\n"); \
+ fprintf (FILE, "\tDC\tA("); \
+ mvs_page_num++; \
+ assemble_name (FILE, mvs_function_name); \
+ fprintf (FILE, ")\n" ); \
+ fprintf (FILE, "\tDS\t0F\n" ); \
+ fprintf (FILE, "\tLTORG\n"); \
+ fprintf (FILE, "\tDS\t0F\n"); \
+ fprintf (FILE, "PGT%d\tEQU\t*\n", function_base_page); \
+ mvs_free_label(); \
+ for ( i = function_base_page; i < mvs_page_num; i++ ) \
+ fprintf (FILE, "\tDC\tA(PG%d)\n", i); \
+}
+#endif /* MACROEPILOGUE */
+
+
+/* Output assembler code for a block containing the constant parts of a
+ trampoline, leaving space for the variable parts.
+
+ On the 370, the trampoline contains these instructions:
+
+ BALR 14,0
+ USING *,14
+ L STATIC_CHAIN_REGISTER,X
+ L 15,Y
+ BR 15
+ X DS 0F
+ Y DS 0F */
+
+#define TRAMPOLINE_TEMPLATE(FILE) \
+{ \
+ ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x05E0)); \
+ ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x5800 | \
+ STATIC_CHAIN_REGNUM << 4)); \
+ ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0xE00A)); \
+ ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x58F0)); \
+ ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0xE00E)); \
+ ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x07FF)); \
+ ASM_OUTPUT_SHORT (FILE, const0_rtx); \
+ ASM_OUTPUT_SHORT (FILE, const0_rtx); \
+ ASM_OUTPUT_SHORT (FILE, const0_rtx); \
+ ASM_OUTPUT_SHORT (FILE, const0_rtx); \
+}
+
+/* Length in units of the trampoline for entering a nested function. */
+
+#define TRAMPOLINE_SIZE 20
+
+/* Emit RTL insns to initialize the variable parts of a trampoline. */
+
+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
+{ \
+ emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 12)), CXT); \
+ emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 16)), FNADDR); \
+}
+
+/* Output assembler code to FILE to increment profiler label # LABELNO
+ for profiling a function entry. */
+
+#define FUNCTION_PROFILER(FILE, LABELNO) \
+ fprintf (FILE, "Error: No profiling available.\n")
+
+/* Define EXIT_IGNORE_STACK if, when returning from a function, the stack
+ pointer does not matter (provided there is a frame pointer). */
+
+#define EXIT_IGNORE_STACK 1
+
+/* Addressing modes, and classification of registers for them. */
+
+/* #define HAVE_POST_INCREMENT */
+/* #define HAVE_POST_DECREMENT */
+
+/* #define HAVE_PRE_DECREMENT */
+/* #define HAVE_PRE_INCREMENT */
+
+/* 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.
+ These definitions are NOT overridden anywhere. */
+
+#define REGNO_OK_FOR_INDEX_P(REGNO) \
+ (((REGNO) > 0 && (REGNO) < 16) \
+ || (reg_renumber[REGNO] > 0 && reg_renumber[REGNO] < 16))
+
+#define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_INDEX_P(REGNO)
+
+#define REGNO_OK_FOR_DATA_P(REGNO) \
+ ((REGNO) < 16 || (unsigned) reg_renumber[REGNO] < 16)
+
+#define REGNO_OK_FOR_FP_P(REGNO) \
+ ((unsigned) ((REGNO) - 16) < 4 || (unsigned) (reg_renumber[REGNO] - 16) < 4)
+
+/* Now macros that check whether X is a register and also,
+ strictly, whether it is in a specified class. */
+
+/* 1 if X is a data register. */
+
+#define DATA_REG_P(X) (REG_P (X) && REGNO_OK_FOR_DATA_P (REGNO (X)))
+
+/* 1 if X is an fp register. */
+
+#define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X)))
+
+/* 1 if X is an address register. */
+
+#define ADDRESS_REG_P(X) (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X)))
+
+/* Maximum number of registers that can appear in a valid memory address. */
+
+#define MAX_REGS_PER_ADDRESS 2
+
+/* Recognize any constant value that is a valid address. */
+
+#define CONSTANT_ADDRESS_P(X) \
+ (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
+ || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE \
+ || (GET_CODE (X) == CONST \
+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF) \
+ || (GET_CODE (X) == CONST \
+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
+ && !SYMBOL_REF_FLAG (XEXP (XEXP (X, 0), 0))))
+
+/* 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
+
+/* 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 all. 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.
+ Some source files that are used after register allocation
+ need to be strict. */
+
+#ifndef REG_OK_STRICT
+
+/* Nonzero if X is a hard reg that can be used as an index or if it is
+ a pseudo reg. */
+
+#define REG_OK_FOR_INDEX_P(X) \
+ ((REGNO(X) > 0 && REGNO(X) < 16) || REGNO(X) >= 20)
+
+/* Nonzero if X is a hard reg that can be used as a base reg or if it is
+ a pseudo reg. */
+
+#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_INDEX_P(X)
+
+#else /* REG_OK_STRICT */
+
+/* Nonzero if X is a hard reg that can be used as an index. */
+
+#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P(REGNO(X))
+
+/* Nonzero if X is a hard reg that can be used as a base reg. */
+
+#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P(REGNO(X))
+
+#endif /* REG_OK_STRICT */
+
+/* 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 actually machine-independent. */
+
+#define COUNT_REGS(X, REGS, FAIL) \
+ if (REG_P (X) && REG_OK_FOR_BASE_P (X)) \
+ REGS += 1; \
+ else if (GET_CODE (X) != CONST_INT || (unsigned) INTVAL (X) >= 4096) \
+ goto FAIL;
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+{ \
+ if (REG_P (X) && REG_OK_FOR_BASE_P (X)) \
+ goto ADDR; \
+ if (GET_CODE (X) == PLUS) \
+ { \
+ int regs = 0; \
+ rtx x0 = XEXP (X, 0); \
+ rtx x1 = XEXP (X, 1); \
+ if (GET_CODE (x0) == PLUS) \
+ { \
+ COUNT_REGS (XEXP (x0, 0), regs, FAIL); \
+ COUNT_REGS (XEXP (x0, 1), regs, FAIL); \
+ COUNT_REGS (x1, regs, FAIL); \
+ if (regs == 2) \
+ goto ADDR; \
+ } \
+ else if (GET_CODE (x1) == PLUS) \
+ { \
+ COUNT_REGS (x0, regs, FAIL); \
+ COUNT_REGS (XEXP (x1, 0), regs, FAIL); \
+ COUNT_REGS (XEXP (x1, 1), regs, FAIL); \
+ if (regs == 2) \
+ goto ADDR; \
+ } \
+ else \
+ { \
+ COUNT_REGS (x0, regs, FAIL); \
+ COUNT_REGS (x1, regs, FAIL); \
+ if (regs != 0) \
+ goto ADDR; \
+ } \
+ } \
+ FAIL: ; \
+}
+
+/* The 370 has no mode dependent addresses. */
+
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
+
+/* 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. */
+
+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
+{ \
+ if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \
+ (X) = gen_rtx (PLUS, SImode, XEXP (X, 0), \
+ copy_to_mode_reg (SImode, XEXP (X, 1))); \
+ if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0))) \
+ (X) = gen_rtx (PLUS, SImode, XEXP (X, 1), \
+ copy_to_mode_reg (SImode, XEXP (X, 0))); \
+ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT) \
+ (X) = gen_rtx (PLUS, SImode, XEXP (X, 1), \
+ force_operand (XEXP (X, 0), 0)); \
+ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT) \
+ (X) = gen_rtx (PLUS, SImode, XEXP (X, 0), \
+ force_operand (XEXP (X, 1), 0)); \
+ if (memory_address_p (MODE, X)) \
+ goto WIN; \
+}
+
+/* Specify the machine mode that this machine uses for the index in the
+ tablejump instruction. */
+
+#define CASE_VECTOR_MODE SImode
+
+/* 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. */
+
+#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
+
+/* Define this if fixuns_trunc is the same as fix_trunc. */
+
+#define FIXUNS_TRUNC_LIKE_FIX_TRUNC
+
+/* We use "unsigned char" as default. */
+
+#define DEFAULT_SIGNED_CHAR 0
+
+/* This is the kind of divide that is easiest to do in the general case. */
+
+#define EASY_DIV_EXPR TRUNC_DIV_EXPR
+
+/* Max number of bytes we can move from memory to memory in one reasonably
+ fast instruction. */
+
+#define MOVE_MAX 256
+
+/* 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 1
+
+/* Define if shifts truncate the shift count which implies one can omit
+ a sign-extension or zero-extension of a shift count. */
+
+/* #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) (OUTPREC != 16)
+
+/* 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'. */
+
+#define PROMOTE_PROTOTYPES
+
+/* Don't perform CSE on function addresses. */
+
+#define NO_FUNCTION_CSE
+
+/* 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
+
+/* 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, OUTERCODE) \
+ case CONST_INT: \
+ if ((unsigned) INTVAL (RTX) < 0xfff) return 1; \
+ case CONST: \
+ case LABEL_REF: \
+ case SYMBOL_REF: \
+ return 2; \
+ case CONST_DOUBLE: \
+ return 4;
+
+/* Tell final.c how to eliminate redundant test instructions. */
+
+/* Here we define machine-dependent flags and fields in cc_status
+ (see `conditions.h'). */
+
+/* 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.
+
+ On the 370, load insns do not alter the cc's. However, in some
+ cases these instructions can make it possibly invalid to use the
+ saved cc's. In those cases we clear out some or all of the saved
+ cc's so they won't be used. */
+
+#define NOTICE_UPDATE_CC(EXP, INSN) \
+{ \
+ rtx exp = (EXP); \
+ if (GET_CODE (exp) == PARALLEL) /* Check this */ \
+ exp = XVECEXP (exp, 0, 0); \
+ if (GET_CODE (exp) != SET) \
+ CC_STATUS_INIT; \
+ else \
+ { \
+ if (XEXP (exp, 0) == cc0_rtx) \
+ { \
+ cc_status.value1 = XEXP (exp, 0); \
+ cc_status.value2 = XEXP (exp, 1); \
+ cc_status.flags = 0; \
+ } \
+ else \
+ { \
+ if (cc_status.value1 \
+ && reg_mentioned_p (XEXP (exp, 0), cc_status.value1)) \
+ cc_status.value1 = 0; \
+ if (cc_status.value2 \
+ && reg_mentioned_p (XEXP (exp, 0), cc_status.value2)) \
+ cc_status.value2 = 0; \
+ switch (GET_CODE (XEXP (exp, 1))) \
+ { \
+ case PLUS: case MINUS: case MULT: /* case UMULT: */ \
+ case DIV: case UDIV: case NEG: case ASHIFT: \
+ case ASHIFTRT: case AND: case IOR: case XOR: \
+ case ABS: case NOT: \
+ CC_STATUS_SET (XEXP (exp, 0), XEXP (exp, 1)); \
+ } \
+ } \
+ } \
+}
+
+
+#define CC_STATUS_SET(V1, V2) \
+{ \
+ cc_status.flags = 0; \
+ cc_status.value1 = (V1); \
+ cc_status.value2 = (V2); \
+ if (cc_status.value1 \
+ && reg_mentioned_p (cc_status.value1, cc_status.value2)) \
+ cc_status.value2 = 0; \
+}
+
+#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \
+{ if (cc_status.flags & CC_NO_OVERFLOW) return NO_OV; return NORMAL; }
+
+/* Control the assembler format that we output. */
+
+#define TEXT_SECTION_ASM_OP "* Program text area"
+#define DATA_SECTION_ASM_OP "* Program data area"
+#define INIT_SECTION_ASM_OP "* Program initialization area"
+#define CTOR_LIST_BEGIN /* NO OP */
+#define CTOR_LIST_END /* NO OP */
+
+/* How to refer to registers in assembler output. This sequence is
+ indexed by compiler's hard-register-number (see above). */
+
+#define REGISTER_NAMES \
+{ "0", "1", "2", "3", "4", "5", "6", "7", \
+ "8", "9", "10", "11", "12", "13", "14", "15", \
+ "0", "2", "4", "6" \
+}
+
+/* How to renumber registers for dbx and gdb. */
+
+#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+
+#define ASM_FILE_START(FILE) fputs ("\tCSECT\n", FILE);
+#define ASM_FILE_END(FILE) fputs ("\tEND\n", FILE);
+#define ASM_IDENTIFY_GCC(FILE)
+#define ASM_COMMENT_START "*"
+#define ASM_APP_OFF ""
+#define ASM_APP_ON ""
+
+#define ASM_OUTPUT_LABEL(FILE, NAME) \
+{ assemble_name (FILE, NAME); fputs ("\tEQU\t*\n", FILE); }
+
+#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) /* NO OP */
+
+#define ASM_GLOBALIZE_LABEL(FILE, NAME) \
+{ fputs ("\tENTRY\t", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE); }
+
+/* MVS externals are limited to 8 characters, upper case only.
+ The '_' is mapped to '@', except for MVS functions, then '#'. */
+
+#define MAX_MVS_LABEL_SIZE 8
+
+#define ASM_OUTPUT_LABELREF(FILE, NAME) \
+{ \
+ char *bp, ch, temp[MAX_MVS_LABEL_SIZE + 1]; \
+ if (strlen (NAME) > MAX_MVS_LABEL_SIZE) \
+ { \
+ strncpy (temp, NAME, MAX_MVS_LABEL_SIZE); \
+ temp[MAX_MVS_LABEL_SIZE] = '\0'; \
+ } \
+ else \
+ strcpy (temp,NAME); \
+ if (!strcmp (temp,"main")) \
+ strcpy (temp,"gccmain"); \
+ if (mvs_function_check (temp)) \
+ ch = '#'; \
+ else \
+ ch = '@'; \
+ for (bp = temp; *bp; bp++) \
+ { \
+ if (islower (*bp)) *bp = toupper (*bp); \
+ if (*bp == '_') *bp = ch; \
+ } \
+ fprintf (FILE, "%s", temp); \
+}
+
+#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
+ sprintf (LABEL, "*%s%d", PREFIX, NUM)
+
+/* Generate internal label. Since we can branch here from off page, we
+ must reload the base register. */
+
+#define ASM_OUTPUT_INTERNAL_LABEL(FILE, PREFIX, NUM) \
+{ \
+ if (!strcmp (PREFIX,"L")) \
+ { \
+ mvs_add_label(NUM); \
+ mvs_label_emitted = 1; \
+ } \
+ fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM); \
+}
+
+/* Generate case label. */
+
+#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \
+ fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM)
+
+/* This is how to output an element of a case-vector that is absolute. */
+
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
+ mvs_check_page (FILE, 4, 0); \
+ fprintf (FILE, "\tDC\tA(L%d)\n", VALUE)
+
+/* This is how to output an element of a case-vector that is relative. */
+
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
+ mvs_check_page (FILE, 4, 0); \
+ fprintf (FILE, "\tDC\tA(L%d-L%d)\n", VALUE, REL)
+
+/* 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) \
+ mvs_check_page (FILE, 8, 4); \
+ fprintf (FILE, "\tS\t13,=F'4'\n\tST\t%s,%d(13)\n", \
+ reg_names[REGNO], STACK_POINTER_OFFSET)
+
+/* 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) \
+ mvs_check_page (FILE, 8, 0); \
+ fprintf (FILE, "\tL\t%s,%d(13)\n\tLA\t13,4(13)\n", \
+ reg_names[REGNO], STACK_POINTER_OFFSET)
+
+/* This is how to output an assembler line defining a `double' constant. */
+
+#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
+ fprintf (FILE, "\tDC\tD'%.18G'\n", (VALUE))
+
+/* This is how to output an assembler line defining a `float' constant. */
+
+#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
+ fprintf (FILE, "\tDC\tE'%.9G'\n", (VALUE))
+
+/* This outputs an integer, if not a CONST_INT must be address constant. */
+
+#define ASM_OUTPUT_INT(FILE, EXP) \
+{ \
+ if (GET_CODE (EXP) == CONST_INT) \
+ { \
+ fprintf (FILE, "\tDC\tF'"); \
+ output_addr_const (FILE, EXP); \
+ fprintf (FILE, "'\n"); \
+ } \
+ else \
+ { \
+ fprintf (FILE, "\tDC\tA("); \
+ output_addr_const (FILE, EXP); \
+ fprintf (FILE, ")\n"); \
+ } \
+}
+
+/* This outputs a short integer. */
+
+#define ASM_OUTPUT_SHORT(FILE, EXP) \
+{ \
+ fprintf (FILE, "\tDC\tX'%04X'\n", INTVAL(EXP) & 0xFFFF); \
+}
+
+/* This outputs a byte sized integer. */
+
+#define ASM_OUTPUT_CHAR(FILE, EXP) \
+ fprintf (FILE, "\tDC\tX'%02X'\n", INTVAL (EXP) )
+
+#define ASM_OUTPUT_BYTE(FILE, VALUE) \
+ fprintf (FILE, "\tDC\tX'%02X'\n", VALUE)
+
+/* This outputs a text string. The string are chopped up to fit into
+ an 80 byte record. Also, control and special characters, interpreted
+ by the IBM assembler, are output numerically. */
+
+#define MVS_ASCII_TEXT_LENGTH 48
+
+#define ASM_OUTPUT_ASCII(FILE, PTR, LEN) \
+{ \
+ int i, j; \
+ int c; \
+ for (j = 0, i = 0; i < LEN; j++, i++) \
+ { \
+ c = PTR[i]; \
+ if (iscntrl (c) || c == '&') \
+ { \
+ if (j % MVS_ASCII_TEXT_LENGTH != 0 ) \
+ fprintf (FILE, "'\n"); \
+ j = -1; \
+ if (c == '&') c = MAP_CHARACTER (c); \
+ fprintf (FILE, "\tDC\tX'%X'\n", c ); \
+ } \
+ else \
+ { \
+ if (j % MVS_ASCII_TEXT_LENGTH == 0) \
+ fprintf (FILE, "\tDC\tC'"); \
+ if ( c == '\'' ) \
+ fprintf (FILE, "%c%c", c, c); \
+ else \
+ fprintf (FILE, "%c", c); \
+ if (j % MVS_ASCII_TEXT_LENGTH == MVS_ASCII_TEXT_LENGTH - 1) \
+ fprintf (FILE, "'\n" ); \
+ } \
+ } \
+ if (j % MVS_ASCII_TEXT_LENGTH != 0) \
+ fprintf (FILE, "'\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) \
+ { \
+ if ((LOG) == 1) \
+ fprintf (FILE, "\tDS\t0H\n" ); \
+ else \
+ fprintf (FILE, "\tDS\t0F\n" ); \
+ } \
+
+/* The maximum length of memory that the IBM assembler will allow in one
+ DS operation. */
+
+#define MAX_CHUNK 32767
+
+/* A C statement to output to the stdio stream FILE an assembler
+ instruction to advance the location counter by SIZE bytes. Those
+ bytes should be zero when loaded. */
+
+#define ASM_OUTPUT_SKIP(FILE, SIZE) \
+{ \
+ int s, k; \
+ for (s = (SIZE); s > 0; s -= MAX_CHUNK) \
+ { \
+ if (s > MAX_CHUNK) \
+ k = MAX_CHUNK; \
+ else \
+ k = s; \
+ fprintf (FILE, "\tDS\tXL%d\n", k); \
+ } \
+}
+
+/* A C statement (sans semicolon) to output to the stdio stream
+ FILE the assembler definition of a common-label named NAME whose
+ size is SIZE bytes. The variable ROUNDED is the size rounded up
+ to whatever alignment the caller wants. */
+
+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
+{ \
+ fputs ("\tENTRY\t", FILE); \
+ assemble_name (FILE, NAME); \
+ fputs ("\n", FILE); \
+ fprintf (FILE, "\tDS\t0F\n"); \
+ ASM_OUTPUT_LABEL (FILE,NAME); \
+ ASM_OUTPUT_SKIP (FILE,SIZE); \
+}
+
+/* A C statement (sans semicolon) to output to the stdio stream
+ FILE the assembler definition of a local-common-label named NAME
+ whose size is SIZE bytes. The variable ROUNDED is the size
+ rounded up to whatever alignment the caller wants. */
+
+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
+{ \
+ fprintf (FILE, "\tDS\t0F\n"); \
+ ASM_OUTPUT_LABEL (FILE,NAME); \
+ ASM_OUTPUT_SKIP (FILE,SIZE); \
+}
+
+/* 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)); \
+}
+
+/* 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 47
+#define TARGET_BS 22
+#define TARGET_TAB 5
+#define TARGET_NEWLINE 21
+#define TARGET_VT 11
+#define TARGET_FF 12
+#define TARGET_CR 13
+
+/* 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.
+ For `%' followed by punctuation, CODE is the punctuation and X is null. */
+
+#define PRINT_OPERAND(FILE, X, CODE) \
+{ \
+ switch (GET_CODE (X)) \
+ { \
+ static char curreg[4]; \
+ case REG: \
+ if (CODE == 'N') \
+ strcpy (curreg, reg_names[REGNO (X) + 1]); \
+ else \
+ strcpy (curreg, reg_names[REGNO (X)]); \
+ fprintf (FILE, "%s", curreg); \
+ break; \
+ case MEM: \
+ { \
+ rtx addr = XEXP (X, 0); \
+ if (CODE == 'O') \
+ { \
+ if (GET_CODE (addr) == PLUS) \
+ fprintf (FILE, "%d", INTVAL (XEXP (addr, 1))); \
+ else \
+ fprintf (FILE, "0"); \
+ } \
+ else if (CODE == 'R') \
+ { \
+ if (GET_CODE (addr) == PLUS) \
+ fprintf (FILE, "%s", reg_names[REGNO (XEXP (addr, 0))]);\
+ else \
+ fprintf (FILE, "%s", reg_names[REGNO (addr)]); \
+ } \
+ else \
+ output_address (XEXP (X, 0)); \
+ } \
+ break; \
+ case SYMBOL_REF: \
+ case LABEL_REF: \
+ mvs_page_lit += 4; \
+ if (SYMBOL_REF_FLAG (X)) fprintf (FILE, "=V("); \
+ else fprintf (FILE, "=A("); \
+ output_addr_const (FILE, X); \
+ fprintf (FILE, ")"); \
+ break; \
+ case CONST_INT: \
+ if (CODE == 'B') \
+ fprintf (FILE, "%d", INTVAL (X) & 0xff); \
+ else if (CODE == 'X') \
+ fprintf (FILE, "%02X", INTVAL (X) & 0xff); \
+ else if (CODE == 'h') \
+ fprintf (FILE, "%d", (INTVAL (X) << 16) >> 16); \
+ else if (CODE == 'H') \
+ { \
+ mvs_page_lit += 2; \
+ fprintf (FILE, "=H'%d'", (INTVAL (X) << 16) >> 16); \
+ } \
+ else \
+ { \
+ mvs_page_lit += 4; \
+ fprintf (FILE, "=F'%d'", INTVAL (X)); \
+ } \
+ break; \
+ case CONST_DOUBLE: \
+ if (GET_MODE (X) == DImode) \
+ { \
+ if (CODE == 'M') \
+ { \
+ mvs_page_lit += 4; \
+ fprintf (FILE, "=XL4'%08X'", CONST_DOUBLE_LOW (X)); \
+ } \
+ else if (CODE == 'L') \
+ { \
+ mvs_page_lit += 4; \
+ fprintf (FILE, "=XL4'%08X'", CONST_DOUBLE_HIGH (X)); \
+ } \
+ else \
+ { \
+ mvs_page_lit += 8; \
+ fprintf (FILE, "=XL8'%08X%08X'", CONST_DOUBLE_LOW (X), \
+ CONST_DOUBLE_HIGH (X)); \
+ } \
+ } \
+ else \
+ { \
+ union { double d; int i[2]; } u; \
+ u.i[0] = CONST_DOUBLE_LOW (X); \
+ u.i[1] = CONST_DOUBLE_HIGH (X); \
+ if (GET_MODE (X) == SFmode) \
+ { \
+ mvs_page_lit += 4; \
+ fprintf (FILE, "=E'%.9G'", u.d); \
+ } \
+ else \
+ { \
+ mvs_page_lit += 8; \
+ fprintf (FILE, "=D'%.18G'", u.d); \
+ } \
+ } \
+ break; \
+ case CONST: \
+ if (GET_CODE (XEXP (X, 0)) == PLUS \
+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \
+ { \
+ mvs_page_lit += 4; \
+ if (SYMBOL_REF_FLAG (XEXP (XEXP (X, 0), 0))) \
+ { \
+ fprintf (FILE, "=V("); \
+ ASM_OUTPUT_LABELREF (FILE, \
+ XSTR (XEXP (XEXP (X, 0), 0), 0)); \
+ fprintf (FILE, ")\n\tA\t%s,=F'%d'", curreg, \
+ INTVAL (XEXP (XEXP (X, 0), 1))); \
+ } \
+ else \
+ { \
+ fprintf (FILE, "=A("); \
+ output_addr_const (FILE, X); \
+ fprintf (FILE, ")"); \
+ } \
+ } \
+ else \
+ { \
+ mvs_page_lit += 4; \
+ fprintf (FILE, "=F'"); \
+ output_addr_const (FILE, X); \
+ fprintf (FILE, "'"); \
+ } \
+ break; \
+ default: \
+ abort(); \
+ } \
+}
+
+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
+{ \
+ rtx breg, xreg, offset, plus; \
+ \
+ switch (GET_CODE (ADDR)) \
+ { \
+ case REG: \
+ fprintf (FILE, "0(%s)", reg_names[REGNO (ADDR)]); \
+ break; \
+ case PLUS: \
+ breg = 0; \
+ xreg = 0; \
+ offset = 0; \
+ if (GET_CODE (XEXP (ADDR, 0)) == PLUS) \
+ { \
+ if (GET_CODE (XEXP (ADDR, 1)) == REG) \
+ breg = XEXP (ADDR, 1); \
+ else \
+ offset = XEXP (ADDR, 1); \
+ plus = XEXP (ADDR, 0); \
+ } \
+ else \
+ { \
+ if (GET_CODE (XEXP (ADDR, 0)) == REG) \
+ breg = XEXP (ADDR, 0); \
+ else \
+ offset = XEXP (ADDR, 0); \
+ plus = XEXP (ADDR, 1); \
+ } \
+ if (GET_CODE (plus) == PLUS) \
+ { \
+ if (GET_CODE (XEXP (plus, 0)) == REG) \
+ { \
+ if (breg) \
+ xreg = XEXP (plus, 0); \
+ else \
+ breg = XEXP (plus, 0); \
+ } \
+ else \
+ { \
+ offset = XEXP (plus, 0); \
+ } \
+ if (GET_CODE (XEXP (plus, 1)) == REG) \
+ { \
+ if (breg) \
+ xreg = XEXP (plus, 1); \
+ else \
+ breg = XEXP (plus, 1); \
+ } \
+ else \
+ { \
+ offset = XEXP (plus, 1); \
+ } \
+ } \
+ else if (GET_CODE (plus) == REG) \
+ { \
+ if (breg) \
+ xreg = plus; \
+ else \
+ breg = plus; \
+ } \
+ else \
+ { \
+ offset = plus; \
+ } \
+ if (offset) \
+ { \
+ if (GET_CODE (offset) == LABEL_REF) \
+ fprintf (FILE, "L%d", \
+ CODE_LABEL_NUMBER (XEXP (offset, 0))); \
+ else \
+ output_addr_const (FILE, offset); \
+ } \
+ else \
+ fprintf (FILE, "0"); \
+ if (xreg) \
+ fprintf (FILE, "(%s,%s)", \
+ reg_names[REGNO (xreg)], reg_names[REGNO (breg)]); \
+ else \
+ fprintf (FILE, "(%s)", reg_names[REGNO (breg)]); \
+ break; \
+ default: \
+ mvs_page_lit += 4; \
+ if (SYMBOL_REF_FLAG (ADDR)) fprintf (FILE, "=V("); \
+ else fprintf (FILE, "=A("); \
+ output_addr_const (FILE, ADDR); \
+ fprintf (FILE, ")"); \
+ break; \
+ } \
+}
diff --git a/gnu/usr.bin/gcc/config/i370/t-i370 b/gnu/usr.bin/gcc/config/i370/t-i370
new file mode 100644
index 00000000000..d20ab385dcc
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i370/t-i370
@@ -0,0 +1,4 @@
+# There is no libgcc for mvs
+LIBGCC =
+INSTALL_LIBGCC =
+LIBGCC1_TEST =
diff --git a/gnu/usr.bin/gcc/config/i370/xm-i370.h b/gnu/usr.bin/gcc/config/i370/xm-i370.h
new file mode 100644
index 00000000000..ac753633070
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i370/xm-i370.h
@@ -0,0 +1,53 @@
+/* Configuration for GNU C-compiler for System/370.
+ Copyright (C) 1989, 1993, 1997 Free Software Foundation, Inc.
+ Contributed by Jan Stein (jan@cd.chalmers.se).
+ Modified for MVS C/370 by Dave Pitts (dpitts@nyx.cs.du.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. */
+
+/* #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_FLOAT_FORMAT IBM_FLOAT_FORMAT
+#define HOST_EBCDIC 1
+
+#define USG
+#ifndef MVS
+#define MVS
+#endif
+
+/* Target machine dependencies. tm.h is a symbolic link to the actual
+ target specific file. */
+
+#include "tm.h"
+
+/* Arguments to use with `exit'. */
+
+#define SUCCESS_EXIT_CODE 0
+#define FATAL_EXIT_CODE 12
+
+#define NO_DBX_FORMAT
+
diff --git a/gnu/usr.bin/gcc/config/i386/cygwin32.asm b/gnu/usr.bin/gcc/config/i386/cygwin32.asm
new file mode 100644
index 00000000000..4ac4c91a3b1
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/cygwin32.asm
@@ -0,0 +1,32 @@
+/* stuff needed for libgcc1 on win32. */
+
+#ifdef L_chkstk
+
+ .global ___chkstk
+ .global __alloca
+___chkstk:
+__alloca:
+ pushl %ecx /* save temp */
+ movl %esp,%ecx /* get sp */
+ addl $0x8,%ecx /* and point to return addr */
+
+probe: cmpl $0x1000,%eax /* > 4k ?*/
+ jb done
+
+ subl $0x1000,%ecx /* yes, move pointer down 4k*/
+ orl $0x0,(%ecx) /* probe there */
+ subl $0x1000,%eax /* decrement count */
+ jmp probe /* and do it again */
+
+done: subl %eax,%ecx
+ orl $0x0,(%ecx) /* less that 4k, just peek here */
+
+ movl %esp,%eax
+ movl %ecx,%esp /* decrement stack */
+
+ movl (%eax),%ecx /* recover saved temp */
+ movl 4(%eax),%eax /* get return address */
+ jmp *%eax
+
+
+#endif
diff --git a/gnu/usr.bin/gcc/config/i386/cygwin32.h b/gnu/usr.bin/gcc/config/i386/cygwin32.h
new file mode 100644
index 00000000000..952d8488b34
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/cygwin32.h
@@ -0,0 +1,207 @@
+/* Operating system specific defines to be used when targeting GCC for
+ hosting on Windows NT 3.x, using a Unix style C library and tools,
+ as distinct from winnt.h, which is used to build GCC for use with a
+ windows style library and tool set and uses the Microsoft tools.
+ Copyright (C) 1995, 1996, 1997 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 YES_UNDERSCORES
+
+#define DBX_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+#include "i386/gas.h"
+#include "dbxcoff.h"
+
+#ifdef CPP_PREDEFINES
+#undef CPP_PREDEFINES
+#endif
+
+#define CPP_PREDEFINES "-Di386 -D_WIN32 \
+ -DPOSIX -D__CYGWIN32__ -DWINNT -D_X86_=1 -D__STDC__=1\
+ -D__stdcall=__attribute__((__stdcall__)) \
+ -D__cdecl=__attribute__((__cdecl__)) \
+ -Asystem(winnt) -Acpu(i386) -Amachine(i386)"
+
+#undef CPP_SPEC
+#define CPP_SPEC "-remap %(cpp_cpu) %[cpp_cpu] %{posix:-D_POSIX_SOURCE}"
+
+/* We have to dynamic link to get to the system DLLs. All of libc, libm and
+ the Unix stuff is in cygwin.dll. The import library is called
+ 'libcygwin.a'. For Windows applications, include more libraries, but
+ always include kernel32. We'd like to specific subsystem windows to
+ ld, but that doesn't work just yet. */
+
+#undef LIB_SPEC
+#define LIB_SPEC "-lcygwin %{mwindows:-luser32 -lgdi32 -lcomdlg32} -lkernel32"
+
+#define LINK_SPEC "%{mwindows:--subsystem windows}"
+
+/* Normally, -lgcc is not needed since everything in it is in the DLL, but we
+ want to allow things to be added to it when installing new versions of
+ GCC without making a new CYGWIN.DLL, so we leave it. */
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "crt0%O%s"
+
+#define SIZE_TYPE "unsigned int"
+#define PTRDIFF_TYPE "int"
+#define WCHAR_UNSIGNED 1
+#define WCHAR_TYPE_SIZE 16
+#define WCHAR_TYPE "short unsigned int"
+#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
+
+/* Emit code to check the stack when allocating more that 4000
+ bytes in one go. */
+
+#define CHECK_STACK_LIMIT 4000
+
+/* By default, target has a 80387, uses IEEE compatible arithmetic,
+ and returns float values in the 387 and needs stack probes */
+#undef TARGET_DEFAULT
+
+#define TARGET_DEFAULT \
+ (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE)
+
+/* This is how to output an assembler line
+ that says to advance the location counter
+ to a multiple of 2**LOG bytes. */
+
+#undef ASM_OUTPUT_ALIGN
+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
+ if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
+
+/* Define this macro if in some cases global symbols from one translation
+ unit may not be bound to undefined symbols in another translation unit
+ without user intervention. For instance, under Microsoft Windows
+ symbols must be explicitly imported from shared libraries (DLLs). */
+#define MULTIPLE_SYMBOL_SPACES
+
+#define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL)
+extern void i386_pe_unique_section ();
+#define UNIQUE_SECTION(DECL,RELOC) i386_pe_unique_section (DECL, RELOC)
+
+#define SUPPORTS_ONE_ONLY 1
+
+/* A C statement to output something to the assembler file to switch to section
+ NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
+ NULL_TREE. Some target formats do not support arbitrary sections. Do not
+ define this macro in such cases. */
+#undef ASM_OUTPUT_SECTION_NAME
+#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
+do { \
+ if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \
+ fprintf (STREAM, "\t.section %s,\"x\"\n", (NAME)); \
+ else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC)) \
+ fprintf (STREAM, "\t.section %s,\"\"\n", (NAME)); \
+ else \
+ fprintf (STREAM, "\t.section %s,\"w\"\n", (NAME)); \
+ /* Functions may have been compiled at various levels of \
+ optimization so we can't use `same_size' here. Instead, \
+ have the linker pick one. */ \
+ if ((DECL) && DECL_ONE_ONLY (DECL)) \
+ fprintf (STREAM, "\t.linkonce %s\n", \
+ TREE_CODE (DECL) == FUNCTION_DECL \
+ ? "discard" : "same_size"); \
+} while (0)
+
+#undef ASM_COMMENT_START
+#define ASM_COMMENT_START " #"
diff --git a/gnu/usr.bin/gcc/config/i386/dgux.c b/gnu/usr.bin/gcc/config/i386/dgux.c
new file mode 100644
index 00000000000..ff36135380c
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/dgux.c
@@ -0,0 +1,190 @@
+/* Subroutines for GNU compiler for Intel 80x86 running DG/ux
+ Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+ Currently maintained by (gcc@dg-rtp.dg.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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <time.h>
+#include "i386/i386.c"
+
+
+extern char *version_string;
+
+struct option
+{
+ char *string;
+ int *variable;
+ int on_value;
+};
+
+static int
+output_option (file, sep, type, name, indent, pos, max)
+ FILE *file;
+ char *sep;
+ char *type;
+ char *name;
+ char *indent;
+ int pos;
+ int max;
+{
+ if (strlen (sep) + strlen (type) + strlen (name) + pos > max)
+ {
+ fprintf (file, indent);
+ return fprintf (file, "%s%s", type, name);
+ }
+ return pos + fprintf (file, "%s%s%s", sep, type, name);
+}
+
+static struct { char *name; int value; } m_options[] = TARGET_SWITCHES;
+
+static void
+output_options (file, f_options, f_len, W_options, W_len,
+ pos, max, sep, indent, term)
+ FILE *file;
+ struct option *f_options;
+ struct option *W_options;
+ int f_len, W_len;
+ int pos;
+ int max;
+ char *indent;
+ char *term;
+{
+ register int j;
+
+ if (optimize)
+ pos = output_option (file, sep, "-O", "", indent, pos, max);
+ if (write_symbols != NO_DEBUG)
+ pos = output_option (file, sep, "-g", "", indent, pos, max);
+/* if (flag_traditional)
+ pos = output_option (file, sep, "-traditional", "", indent, pos, max);*/
+ if (profile_flag)
+ pos = output_option (file, sep, "-p", "", indent, pos, max);
+ if (profile_block_flag)
+ pos = output_option (file, sep, "-a", "", indent, pos, max);
+
+ for (j = 0; j < f_len; j++)
+ if (*f_options[j].variable == f_options[j].on_value)
+ pos = output_option (file, sep, "-f", f_options[j].string,
+ indent, pos, max);
+
+ for (j = 0; j < W_len; j++)
+ if (*W_options[j].variable == W_options[j].on_value)
+ pos = output_option (file, sep, "-W", W_options[j].string,
+ indent, pos, max);
+
+ for (j = 0; j < sizeof m_options / sizeof m_options[0]; j++)
+ if (m_options[j].name[0] != '\0'
+ && m_options[j].value > 0
+ && ((m_options[j].value & target_flags)
+ == m_options[j].value))
+ pos = output_option (file, sep, "-m", m_options[j].name,
+ indent, pos, max);
+
+ pos = output_option (file, sep, "-mcpu=", ix86_cpu_string, indent, pos, max);
+ pos = output_option (file, sep, "-march=", ix86_arch_string, indent, pos, max);
+ fprintf (file, term);
+}
+
+/* Output to FILE the start of the assembler file. */
+
+void
+output_file_start (file, f_options, f_len, W_options, W_len)
+ FILE *file;
+ struct option *f_options;
+ struct option *W_options;
+ int f_len, W_len;
+{
+ register int pos;
+
+ output_file_directive (file, main_input_filename);
+ fprintf (file, "\t.version\t\"01.01\"\n"); \
+ /* Switch to the data section so that the coffsem symbol and the
+ gcc2_compiled. symbol aren't in the text section. */
+ data_section ();
+
+ pos = fprintf (file, "\n// cc1 (%s) arguments:", VERSION_STRING);
+ output_options (file, f_options, f_len, W_options, W_len,
+ pos, 75, " ", "\n// ", "\n\n");
+
+#ifdef TARGET_IDENTIFY_REVISION
+ if (TARGET_IDENTIFY_REVISION)
+ {
+ char indent[256];
+
+ time_t now = time ((time_t *)0);
+ sprintf (indent, "]\"\n\t%s\t \"@(#)%s [", IDENT_ASM_OP, main_input_filename);
+ fprintf (file, indent+3);
+ pos = fprintf (file, "gcc %s, %.24s,", VERSION_STRING, ctime (&now));
+ output_options (file, f_options, f_len, W_options, W_len,
+ pos, 150 - strlen (indent), " ", indent, "]\"\n\n");
+ }
+#endif /* TARGET_IDENTIFY_REVISION */
+}
+
+#ifndef CROSS_COMPILE
+#if defined (_abort_aux)
+/* Debugging aid to be registered via `atexit'. See the definition
+ of abort in dgux.h. */
+void
+abort_aux ()
+{
+ extern int insn_;
+ extern char * file_;
+ extern int line_;
+ static int done;
+ rtx line_note;
+
+ if (done++)
+ return;
+ if (file_ || line_)
+ {
+ if (write_symbols != NO_DEBUG)
+ {
+ for (line_note = (rtx) insn_ ; line_note != 0 ; line_note = PREV_INSN (line_note))
+ if (GET_CODE (line_note) == NOTE && NOTE_LINE_NUMBER (line_note) > 0)
+ break;
+ if (line_note != 0)
+ {
+ error_with_file_and_line (NOTE_SOURCE_FILE (line_note),
+ NOTE_LINE_NUMBER (line_note),
+ "Internal gcc abort from %s:%d",
+ file_ ? file_ : "<nofile>", line_);
+ if (insn_ && file_ && strcmp (file_, "toplev.c"))
+ {
+ error_with_file_and_line (NOTE_SOURCE_FILE (line_note),
+ NOTE_LINE_NUMBER (line_note),
+ "The local variable `insn' has the value:", 0);
+ debug_rtx ((rtx) insn_);
+ }
+ }
+ }
+ if (write_symbols == NO_DEBUG || line_note == 0)
+ {
+ error ("Internal gcc abort from %s:%d",
+ file_ ? file_ : "<nofile>", line_);
+ if (insn_ && file_ && strcmp (file_, "toplev.c"))
+ {
+ error ("The local variable `insn' has the value:", 0);
+ debug_rtx ((rtx) insn_);
+ }
+ }
+ }
+}
+#endif
+#endif
+
+
diff --git a/gnu/usr.bin/gcc/config/i386/dgux.h b/gnu/usr.bin/gcc/config/i386/dgux.h
new file mode 100644
index 00000000000..ce0c8235585
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/dgux.h
@@ -0,0 +1,265 @@
+/* Target definitions for GNU compiler for Intel 80x86 running DG/ux
+ Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Currently maintained by gcc@dg-rtp.dg.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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* for now, we are just like the sysv4 version with a
+ few hacks
+*/
+
+#include "i386/sysv4.h"
+
+#ifndef VERSION_INFO2
+#define VERSION_INFO2 "$Revision: 1.1 $"
+#endif
+
+#ifndef VERSION_STRING
+#define VERSION_STRING version_string
+#endif
+
+/* Identify the compiler. */
+/* TARGET_VERSION used by toplev.c VERSION_STRING used by -midentify-revision */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (%s%s, %s)", \
+ VERSION_INFO1, VERSION_INFO2, __DATE__)
+#undef VERSION_INFO1
+#define VERSION_INFO1 "ix86 DG/ux, "
+
+/* Augment TARGET_SWITCHES with the MXDB options. */
+#define MASK_STANDARD 0x40000000 /* Retain standard information */
+#define MASK_NOLEGEND 0x20000000 /* Discard legend information */
+#define MASK_EXTERNAL_LEGEND 0x10000000 /* Make external legends */
+#define MASK_IDENTIFY_REVISION 0x08000000 /* Emit 'ident' to .s */
+#define MASK_WARN_PASS_STRUCT 0x04000000 /* Emit 'ident' to .s */
+
+#define TARGET_STANDARD (target_flags & MASK_STANDARD)
+#define TARGET_NOLEGEND (target_flags & MASK_NOLEGEND)
+#define TARGET_EXTERNAL_LEGEND (target_flags & MASK_EXTERNAL_LEGEND)
+#define TARGET_IDENTIFY_REVISION (target_flags & MASK_IDENTIFY_REVISION)
+#define TARGET_WARN_PASS_STRUCT (target_flags & MASK_WARN_PASS_STRUCT)
+
+#undef SUBTARGET_SWITCHES
+#define SUBTARGET_SWITCHES \
+ { "standard", MASK_STANDARD }, \
+ { "legend", -MASK_NOLEGEND }, \
+ { "no-legend", MASK_NOLEGEND }, \
+ { "external-legend", MASK_EXTERNAL_LEGEND }, \
+ { "identify-revision", MASK_IDENTIFY_REVISION }, \
+ { "warn-passed-structs", MASK_WARN_PASS_STRUCT },
+
+#undef DWARF_DEBUGGING_INFO
+#define DWARF_DEBUGGING_INFO
+
+/*
+ allow -gstabs so that those who have gnu-as installed
+ can debug c++ programs.
+*/
+#undef DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO
+
+#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
+
+/* Override svr[34].h. */
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) \
+ output_file_start (FILE, f_options, sizeof f_options / sizeof f_options[0], \
+ W_options, sizeof W_options / sizeof W_options[0])
+
+/* ix86 abi specified type for wchar_t */
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "long int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+
+/* Some machines may desire to change what optimizations are performed for
+ various optimization levels. This macro, if defined, is executed once
+ just after the optimization level is determined and before the remainder
+ of the command options have been parsed. Values set in this macro are
+ used as the default values for the other command line options.
+
+ LEVEL is the optimization level specified; 2 if -O2 is specified,
+ 1 if -O is specified, and 0 if neither is specified. */
+
+/* This macro used to store 0 in flag_signed_bitfields.
+ Not only is that misuse of this macro; the whole idea is wrong.
+
+ The GNU C dialect makes bitfields signed by default,
+ regardless of machine type. Making any machine inconsistent in this
+ regard is bad for portability.
+
+ I chose to make bitfields signed by default because this is consistent
+ with the way ordinary variables are handled: `int' equals `signed int'.
+ If there is a good reason to prefer making bitfields unsigned by default,
+ it cannot have anything to do with the choice of machine.
+ If the reason is good enough, we should change the convention for all machines.
+
+ -- rms, 20 July 1991. */
+
+/*
+ this really should go into dgux-local.h
+*/
+
+#undef OPTIMIZATION_OPTIONS
+#define OPTIMIZATION_OPTIONS(LEVEL) \
+ do { \
+ extern int flag_signed_bitfields; \
+ flag_signed_bitfields = 0; \
+ abort_helper (); \
+ optimization_options (LEVEL); \
+ } while (0)
+
+
+/* The normal location of the `ld' and `as' programs */
+
+#undef MD_EXEC_PREFIX
+#define MD_EXEC_PREFIX "/usr/bin/"
+
+/* The normal location of the various *crt*.o files is the */
+
+#undef MD_STARTFILE_PREFIX
+#define MD_STARTFILE_PREFIX "/usr/lib/"
+
+/* Macros to be automatically defined.
+ __CLASSIFY_TYPE__ is used in the <varargs.h> and <stdarg.h> header
+ files with DG/UX revision 5.40 and later. This allows GNU CC to
+ operate without installing the header files. */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Di386 -D__ix86 -Dunix -DDGUX -D__CLASSIFY_TYPE__=2\
+ -Asystem(unix) -Asystem(svr4) -Acpu(i386) -Amachine(i386)"
+
+ /*
+ If not -ansi, -traditional, or restricting include files to one
+ specific source target, specify full DG/UX features.
+ */
+#undef CPP_SPEC
+#define CPP_SPEC "%{!ansi:%{!traditional:-D__OPEN_NAMESPACE__}}"
+
+/* Assembler support (legends for mxdb). */
+#undef ASM_SPEC
+#define ASM_SPEC "\
+%{mno-legend:%{mstandard:-Wc,off}}\
+%{g:%{!mno-legend:-Wc,-fix-bb,-s\"%i\"\
+%{traditional:,-lc}%{!traditional:,-lansi-c}\
+%{mstandard:,-keep-std}\
+%{mexternal-legend:,-external}}}"
+
+/* Override svr4.h. */
+
+/* hassey 3/12/94 keep svr4 ASM_FINAL_SPEC allows -pipe to work */
+
+/* Linker and library spec's.
+ -static, -shared, -symbolic, -h* and -z* access AT&T V.4 link options.
+ -svr4 instructs gcc to place /usr/lib/values-X[cat].o on link the line.
+ The absence of -msvr4 indicates linking done in a COFF environment and
+ adds the link script to the link line. In all environments, the first
+ and last objects are crtbegin.o and crtend.o.
+ When the -G link option is used (-shared and -symbolic) a final link is
+ not being done. */
+
+#undef LIB_SPEC
+#define LIB_SPEC \
+"%{!shared:%{!symbolic:-lc}}"
+
+#undef LINK_SPEC
+#define LINK_SPEC "%{z*} %{h*} %{v:-V} \
+ %{static:-dn -Bstatic} \
+ %{shared:-G -dy} \
+ %{symbolic:-Bsymbolic -G -dy} \
+ %{pg:-L/usr/lib/libp}%{p:-L/usr/lib/libp}"
+
+#ifdef CROSS_COMPILE
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "%{!shared:%{!symbolic:%{pg:gcrt1.o%s} \
+ %{!pg:%{p:mcrt1.o%s} \
+ %{!p:crt1.o%s}}}} \
+ %{pg:gcrti.o%s}%{!pg:crti.o%s} \
+ crtbegin.o%s \
+ %{ansi:values-Xc.o%s} \
+ %{!ansi:%{traditional:values-Xt.o%s} \
+ %{!traditional:values-Xa.o%s}}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtend.o%s %{pg:gcrtn.o}%{!pg:crtn.o%s}"
+
+#else
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "%{!shared:%{!symbolic:%{pg:gcrt1.o%s} \
+ %{!pg:%{p:/lib/mcrt1.o%s} \
+ %{!p:/lib/crt1.o%s}}} \
+ %{pg:gcrti.o%s}%{!pg:/lib/crti.o%s}} \
+ crtbegin.o%s \
+ %{ansi:/lib/values-Xc.o%s} \
+ %{!ansi:%{traditional:/lib/values-Xt.o%s} \
+ %{!traditional:/lib/values-Xa.o%s}}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtend.o%s %{pg:gcrtn.o}%{!pg:/lib/crtn.o}"
+
+#endif /* CROSS_COMPILE */
+
+#if !defined (no_abort) || defined (CRT_BEGIN) || defined (CRT_END)
+#undef abort
+
+char insn; int insn_; char * file_; int line_;
+#define abort() \
+ (insn_ = (int) insn, \
+ file_ = __FILE__, \
+ line_ = __LINE__, \
+ fancy_abort ())
+#define abort_helper() \
+ do { \
+ extern void abort_aux (); \
+ atexit (abort_aux); \
+ } while (0)
+#define _abort_aux
+#endif /* no abort */
+
+/* The maximum alignment which the object file format can support.
+ page alignment would seem to be enough */
+#undef MAX_OFILE_ALIGNMENT
+#define MAX_OFILE_ALIGNMENT 0x1000
+
+/* Must use data section for relocatable constants when pic. */
+#undef SELECT_RTX_SECTION
+#define SELECT_RTX_SECTION(MODE,RTX) \
+{ \
+ if (flag_pic && symbolic_operand (RTX)) \
+ data_section (); \
+ else \
+ const_section (); \
+}
+
+/* This supplements FUNCTION_ARG's definition in i386.h to check
+ TARGET_WARN_PASS_STRUCT */
+
+#undef FUNCTION_ARG
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
+((((MODE) == BLKmode && TARGET_WARN_PASS_STRUCT) ? \
+ warning ("argument is a structure"),0 : 0), \
+ (function_arg (&CUM, MODE, TYPE, NAMED)))
+
+/* Add .align 1 to avoid .backalign bug in assembler */
+#undef CONST_SECTION_ASM_OP
+#define CONST_SECTION_ASM_OP ".section\t.rodata\n\t.align 1"
diff --git a/gnu/usr.bin/gcc/config/i386/freebsd-elf.h b/gnu/usr.bin/gcc/config/i386/freebsd-elf.h
new file mode 100644
index 00000000000..252ebf5cf84
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/freebsd-elf.h
@@ -0,0 +1,187 @@
+/* Definitions for Intel 386 running FreeBSD with ELF format
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ Contributed by Eric Youngdale.
+ Modified for stabs-in-ELF by H.J. Lu.
+ Adapted from GNU/Linux version by John Polstra.
+
+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 TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (i386 FreeBSD/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 "int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Dunix -D__ELF__ -D__FreeBSD__=2 -Asystem(FreeBSD)"
+
+#undef CPP_SPEC
+#define CPP_SPEC "%(cpp_cpu) %[cpp_cpu] %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}"
+
+#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 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
+
+/* Provide a LINK_SPEC appropriate for FreeBSD. 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. */
+
+#undef LINK_SPEC
+#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
+ %{!shared: \
+ %{!ibcs: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \
+ %{static:-static}}}"
+
+/* Get perform_* macros to build libgcc.a. */
diff --git a/gnu/usr.bin/gcc/config/i386/gmon-sol2.c b/gnu/usr.bin/gcc/config/i386/gmon-sol2.c
new file mode 100644
index 00000000000..c0743958f90
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/gmon-sol2.c
@@ -0,0 +1,402 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Re rework of the solaris 2 version of gmon by J.W.Hawtin 12/8/1996
+ * Does not work right yet.
+ */
+
+/*
+ * This is a modified gmon.c by J.W.Hawtin <J.W.Hawtin@lboro.ac.uk>,
+ * 14/8/96 based on the original gmon.c in GCC and the hacked version
+ * solaris 2 sparc version (config/sparc/gmon-sol.c) by Mark Eichin. To do
+ * process profiling on solaris 2.4 X86
+ *
+ * It must be used in conjunction with sol2-gc1.asm, which is used to start
+ * and stop process monitoring.
+ *
+ * Differences.
+ *
+ * On Solaris 2 _mcount is called my library functions not mcount, so support
+ * has been added for both.
+ *
+ * Also the prototype for profil() is different
+ *
+ * Solaris 2 does not seem to have char *minbrk whcih allows the setting of
+ * the minimum SBRK region so this code has been removed and lets pray malloc
+ * does not mess it up.
+ *
+ * Notes
+ *
+ * This code could easily be integrated with the original gmon.c and perhaps
+ * should be.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)gmon.c 5.3 (Berkeley) 5/22/91";
+#endif /* not lint */
+
+#if 0
+#include <unistd.h>
+
+#endif
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#if 0
+#include "i386/gmon.h"
+#else
+
+struct phdr {
+ char *lpc;
+ char *hpc;
+ int ncnt;
+};
+
+
+#define HISTFRACTION 2
+#define HISTCOUNTER unsigned short
+#define HASHFRACTION 1
+#define ARCDENSITY 2
+#define MINARCS 50
+#define BASEADDRESS 0x8000000 /* On Solaris 2 X86 all executables start here
+ and not at 0 */
+
+struct tostruct {
+ char *selfpc;
+ long count;
+ unsigned short link;
+};
+struct rawarc {
+ unsigned long raw_frompc;
+ unsigned long raw_selfpc;
+ long raw_count;
+};
+#define ROUNDDOWN(x,y) (((x)/(y))*(y))
+#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y))
+#endif
+
+/* char *minbrk; */
+
+#ifdef __alpha
+extern char *sbrk ();
+#endif
+
+ /*
+ * froms is actually a bunch of unsigned shorts indexing tos
+ */
+static int profiling = 3;
+static unsigned short *froms;
+static struct tostruct *tos = 0;
+static long tolimit = 0;
+static char *s_lowpc = 0;
+static char *s_highpc = 0;
+static unsigned long s_textsize = 0;
+
+static int ssiz;
+static char *sbuf;
+static int s_scale;
+ /* see profil(2) where this is describe (incorrectly) */
+#define SCALE_1_TO_1 0x10000L
+
+#define MSG "No space for profiling buffer(s)\n"
+
+extern int errno;
+
+monstartup(lowpc, highpc)
+ char *lowpc;
+ char *highpc;
+{
+ int monsize;
+ char *buffer;
+ register int o;
+
+ /*
+ * round lowpc and highpc to multiples of the density we're using
+ * so the rest of the scaling (here and in gprof) stays in ints.
+ */
+ lowpc = (char *)
+ ROUNDDOWN((unsigned)lowpc, HISTFRACTION*sizeof(HISTCOUNTER));
+ s_lowpc = lowpc;
+ highpc = (char *)
+ ROUNDUP((unsigned)highpc, HISTFRACTION*sizeof(HISTCOUNTER));
+ s_highpc = highpc;
+ s_textsize = highpc - lowpc;
+ monsize = (s_textsize / HISTFRACTION) + sizeof(struct phdr);
+ buffer = (char *) sbrk( monsize );
+ if ( buffer == (char *) -1 ) {
+ write( 2 , MSG , sizeof(MSG) );
+ return;
+ }
+ froms = (unsigned short *) sbrk( s_textsize / HASHFRACTION );
+ if ( froms == (unsigned short *) -1 ) {
+ write( 2 , MSG , sizeof(MSG) );
+ froms = 0;
+ return;
+ }
+ tolimit = s_textsize * ARCDENSITY / 100;
+ if ( tolimit < MINARCS ) {
+ tolimit = MINARCS;
+ } else if ( tolimit > 65534 ) {
+ tolimit = 65534;
+ }
+ tos = (struct tostruct *) sbrk( tolimit * sizeof( struct tostruct ) );
+ if ( tos == (struct tostruct *) -1 ) {
+ write( 2 , MSG , sizeof(MSG) );
+ froms = 0;
+ tos = 0;
+ return;
+ }
+/* minbrk = (char *) sbrk(0);*/
+ tos[0].link = 0;
+ sbuf = buffer;
+ ssiz = monsize;
+ ( (struct phdr *) buffer ) -> lpc = lowpc;
+ ( (struct phdr *) buffer ) -> hpc = highpc;
+ ( (struct phdr *) buffer ) -> ncnt = ssiz;
+ monsize -= sizeof(struct phdr);
+ if ( monsize <= 0 )
+ return;
+ o = highpc - lowpc;
+ if( monsize < o )
+#ifndef hp300
+ s_scale = ( (float) monsize / o ) * SCALE_1_TO_1;
+#else /* avoid floating point */
+ {
+ int quot = o / monsize;
+
+ if (quot >= 0x10000)
+ s_scale = 1;
+ else if (quot >= 0x100)
+ s_scale = 0x10000 / quot;
+ else if (o >= 0x800000)
+ s_scale = 0x1000000 / (o / (monsize >> 8));
+ else
+ s_scale = 0x1000000 / ((o << 8) / monsize);
+ }
+#endif
+ else
+ s_scale = SCALE_1_TO_1;
+ moncontrol(1);
+}
+
+_mcleanup()
+{
+ int fd;
+ int fromindex;
+ int endfrom;
+ char *frompc;
+ int toindex;
+ struct rawarc rawarc;
+
+ moncontrol(0);
+ fd = creat( "gmon.out" , 0666 );
+ if ( fd < 0 ) {
+ perror( "mcount: gmon.out" );
+ return;
+ }
+# ifdef DEBUG
+ fprintf( stderr , "[mcleanup] sbuf 0x%x ssiz %d\n" , sbuf , ssiz );
+# endif DEBUG
+
+ write( fd , sbuf , ssiz );
+ endfrom = s_textsize / (HASHFRACTION * sizeof(*froms));
+ for ( fromindex = 0 ; fromindex < endfrom ; fromindex++ ) {
+ if ( froms[fromindex] == 0 ) {
+ continue;
+ }
+ frompc = s_lowpc + (fromindex * HASHFRACTION * sizeof(*froms));
+ for (toindex=froms[fromindex]; toindex!=0; toindex=tos[toindex].link) {
+# ifdef DEBUG
+ fprintf( stderr ,
+ "[mcleanup] frompc 0x%x selfpc 0x%x count %d\n" ,
+ frompc , tos[toindex].selfpc , tos[toindex].count );
+# endif DEBUG
+ rawarc.raw_frompc = (unsigned long) frompc;
+ rawarc.raw_selfpc = (unsigned long) tos[toindex].selfpc;
+ rawarc.raw_count = tos[toindex].count;
+ write( fd , &rawarc , sizeof rawarc );
+ }
+ }
+ close( fd );
+}
+
+/* Solaris 2 libraries use _mcount. */
+asm(".globl _mcount; _mcount: jmp internal_mcount");
+/* This is for compatibility with old versions of gcc which used mcount. */
+asm(".globl mcount; mcount: jmp internal_mcount");
+
+internal_mcount()
+{
+ register char *selfpc;
+ register unsigned short *frompcindex;
+ register struct tostruct *top;
+ register struct tostruct *prevtop;
+ register long toindex;
+
+ /*
+ * find the return address for mcount,
+ * and the return address for mcount's caller.
+ */
+
+ /* selfpc = pc pushed by mcount call.
+ This identifies the function that was just entered. */
+ selfpc = (void *) __builtin_return_address (0);
+ /* frompcindex = pc in preceding frame.
+ This identifies the caller of the function just entered. */
+ frompcindex = (void *) __builtin_return_address (1);
+
+ /*
+ * check that we are profiling
+ * and that we aren't recursively invoked.
+ */
+ if (profiling) {
+ goto out;
+ }
+ profiling++;
+ /*
+ * check that frompcindex is a reasonable pc value.
+ * for example: signal catchers get called from the stack,
+ * not from text space. too bad.
+ */
+ frompcindex = (unsigned short *)((long)frompcindex - (long)s_lowpc);
+ if ((unsigned long)frompcindex > s_textsize) {
+ goto done;
+ }
+ frompcindex =
+ &froms[((long)frompcindex) / (HASHFRACTION * sizeof(*froms))];
+ toindex = *frompcindex;
+ if (toindex == 0) {
+ /*
+ * first time traversing this arc
+ */
+ toindex = ++tos[0].link;
+ if (toindex >= tolimit) {
+ goto overflow;
+ }
+ *frompcindex = toindex;
+ top = &tos[toindex];
+ top->selfpc = selfpc;
+ top->count = 1;
+ top->link = 0;
+ goto done;
+ }
+ top = &tos[toindex];
+ if (top->selfpc == selfpc) {
+ /*
+ * arc at front of chain; usual case.
+ */
+ top->count++;
+ goto done;
+ }
+ /*
+ * have to go looking down chain for it.
+ * top points to what we are looking at,
+ * prevtop points to previous top.
+ * we know it is not at the head of the chain.
+ */
+ for (; /* goto done */; ) {
+ if (top->link == 0) {
+ /*
+ * top is end of the chain and none of the chain
+ * had top->selfpc == selfpc.
+ * so we allocate a new tostruct
+ * and link it to the head of the chain.
+ */
+ toindex = ++tos[0].link;
+ if (toindex >= tolimit) {
+ goto overflow;
+ }
+ top = &tos[toindex];
+ top->selfpc = selfpc;
+ top->count = 1;
+ top->link = *frompcindex;
+ *frompcindex = toindex;
+ goto done;
+ }
+ /*
+ * otherwise, check the next arc on the chain.
+ */
+ prevtop = top;
+ top = &tos[top->link];
+ if (top->selfpc == selfpc) {
+ /*
+ * there it is.
+ * increment its count
+ * move it to the head of the chain.
+ */
+ top->count++;
+ toindex = prevtop->link;
+ prevtop->link = top->link;
+ top->link = *frompcindex;
+ *frompcindex = toindex;
+ goto done;
+ }
+
+ }
+done:
+ profiling--;
+ /* and fall through */
+out:
+ return; /* normal return restores saved registers */
+
+overflow:
+ profiling++; /* halt further profiling */
+# define TOLIMIT "mcount: tos overflow\n"
+ write(2, TOLIMIT, sizeof(TOLIMIT));
+ goto out;
+}
+
+/*
+ * Control profiling
+ * profiling is what mcount checks to see if
+ * all the data structures are ready.
+ */
+moncontrol(mode)
+ int mode;
+{
+ if (mode)
+ {
+ /* start */
+ profil((unsigned short *)(sbuf + sizeof(struct phdr)),
+ ssiz - sizeof(struct phdr),
+ (int)s_lowpc, s_scale);
+
+ profiling = 0;
+ } else {
+ /* stop */
+ profil((unsigned short *)0, 0, 0, 0);
+ profiling = 3;
+ }
+}
diff --git a/gnu/usr.bin/gcc/config/i386/go32-rtems.h b/gnu/usr.bin/gcc/config/i386/go32-rtems.h
new file mode 100644
index 00000000000..282465b249b
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/go32-rtems.h
@@ -0,0 +1,32 @@
+/* Configuration for an i386 running RTEMS on top of MS-DOS with
+ djgpp/go32 v1.x.
+
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ Contributed by Joel Sherrill (joel@OARcorp.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/go32.h"
+
+/* Specify predefined symbols in preprocessor. */
+
+#ifdef CPP_PREDEFINES
+#undef CPP_PREDEFINES
+#endif
+#define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DMSDOS -Drtems -D__rtems__ \
+ -Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386) -Asystem(rtems)"
diff --git a/gnu/usr.bin/gcc/config/i386/mingw32.h b/gnu/usr.bin/gcc/config/i386/mingw32.h
new file mode 100644
index 00000000000..984a3692c30
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/mingw32.h
@@ -0,0 +1,93 @@
+/* Operating system specific defines to be used when targeting GCC for
+ hosting on Windows32, using GNU tools and the Windows32 API Library,
+ as distinct from winnt.h, which is used to build GCC for use with a
+ windows style library and tool set and uses the Microsoft tools.
+ Copyright (C) 1997 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. */
+
+/* Most of this is the same as for Cygwin32, except for changing some
+ specs. */
+
+#include "i386/cygwin32.h"
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Di386 -D_WIN32 -DWIN32 -D__WIN32__ \
+ -D__MINGW32__ -DWINNT -D_X86_=1 -D__STDC__=1\
+ -D__stdcall=__attribute__((__stdcall__)) \
+ -D__cdecl=__attribute__((__cdecl__)) \
+ -Asystem(winnt) -Acpu(i386) -Amachine(i386)"
+
+/* Specific a different directory for the standard include files. */
+#undef STANDARD_INCLUDE_DIR
+#define STANDARD_INCLUDE_DIR "/usr/mingw32/include"
+
+#define STANDARD_INCLUDE_COMPONENT "MINGW32"
+
+/* For Windows applications, include more libraries, but always include
+ kernel32. */
+#undef LIB_SPEC
+#define LIB_SPEC \
+"%{mwindows:-luser32 -lgdi32 -lcomdlg32} -lkernel32 -ladvapi32 -lshell32"
+
+/* Include in the mingw32 libraries with libgcc */
+#undef LIBGCC_SPEC
+#define LIBGCC_SPEC "-lmingw32 -lgcc -lmoldname -lcrtdll"
+
+/* Specify a different entry point when linking a DLL */
+#undef LINK_SPEC
+#define LINK_SPEC \
+"%{mwindows:--subsystem windows} %{mdll:--dll -e _DllMainCRTStartup@12}"
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "%{mdll:dllcrt1%O%s} %{!mdll:crt1%O%s}"
+
+#define MATH_LIBRARY "-lcrtdll"
+
+/* Output STRING, a string representing a filename, to FILE. We canonicalize
+ it to be in MS-DOS format. */
+#define OUTPUT_QUOTED_STRING(FILE, STRING) \
+do { \
+ char c; \
+ \
+ putc ('\"', asm_file); \
+ if (STRING[1] == ':' \
+ && (STRING[2] == '/' || STRING[2] == '\\')) \
+ { \
+ putc ('/', asm_file); \
+ putc ('/', asm_file); \
+ putc (*string, asm_file); \
+ string += 2; \
+ } \
+ \
+ while ((c = *string++) != 0) \
+ { \
+ if (c == '\\') \
+ c = '/'; \
+ \
+ if (c == '\"') \
+ putc ('\\', asm_file); \
+ putc (c, asm_file); \
+ } \
+ \
+ putc ('\"', asm_file); \
+} while (0)
+
+/* Dwarf2 exception information does not work on this system for some
+ unknown reason, so turn it off. */
+#undef INCOMING_RETURN_ADDR_RTX
diff --git a/gnu/usr.bin/gcc/config/i386/moss.h b/gnu/usr.bin/gcc/config/i386/moss.h
new file mode 100644
index 00000000000..dadf3d86af2
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/moss.h
@@ -0,0 +1,34 @@
+/* Definitions for Intel 386 running MOSS
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ Contributed by Bryan Ford <baford@cs.utah.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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* I believe in reuse... */
+#include "i386/linux.h"
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-D__ELF__ -Di386 -Dmoss -Asystem(posix) -Acpu(i386) -Amachine(i386)"
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "crt0.o%s"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtn.o%s"
+
+#undef LINK_SPEC
+
diff --git a/gnu/usr.bin/gcc/config/i386/ptx4-i.h b/gnu/usr.bin/gcc/config/i386/ptx4-i.h
new file mode 100644
index 00000000000..fdf21a471f1
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/ptx4-i.h
@@ -0,0 +1,247 @@
+/* Target definitions for GNU compiler for Intel 80386 running Dynix/ptx v4
+ Copyright (C) 1996 Free Software Foundation, Inc.
+
+ Modified from sysv4.h
+ Originally written by Ron Guilmette (rfg@netcom.com).
+ Modified by Tim Wright (timw@sequent.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 "ptx4.h" /* Rest of definitions (non architecture dependent) */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (i386 Sequent Dynix/ptx Version 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. _SEQUENT_ 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_SEQUENT_ -Asystem(unix) -Asystem(ptx4) -Acpu(i386) -Amachine(i386)"
+
+/* This is how to output assembly code to define a `float' constant.
+ We always have to use a .long pseudo-op to do this because the native
+ SVR4 ELF assembler is buggy and it generates incorrect values when we
+ try to use the .float pseudo-op instead. */
+
+#undef ASM_OUTPUT_FLOAT
+#define ASM_OUTPUT_FLOAT(FILE,VALUE) \
+do { long value; \
+ REAL_VALUE_TO_TARGET_SINGLE ((VALUE), value); \
+ if (sizeof (int) == sizeof (long)) \
+ fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value); \
+ else \
+ fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value); \
+ } while (0)
+
+/* This is how to output assembly code to define a `double' constant.
+ We always have to use a pair of .long pseudo-ops to do this because
+ the native SVR4 ELF assembler is buggy and it generates incorrect
+ values when we try to use the the .double pseudo-op instead. */
+
+#undef ASM_OUTPUT_DOUBLE
+#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
+do { long value[2]; \
+ REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), value); \
+ if (sizeof (int) == sizeof (long)) \
+ { \
+ fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[0]); \
+ fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[1]); \
+ } \
+ else \
+ { \
+ fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[0]); \
+ fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[1]); \
+ } \
+ } while (0)
+
+
+#undef ASM_OUTPUT_LONG_DOUBLE
+#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \
+do { long value[3]; \
+ REAL_VALUE_TO_TARGET_LONG_DOUBLE ((VALUE), value); \
+ if (sizeof (int) == sizeof (long)) \
+ { \
+ fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[0]); \
+ fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[1]); \
+ fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[2]); \
+ } \
+ else \
+ { \
+ fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[0]); \
+ fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[1]); \
+ fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[2]); \
+ } \
+ } while (0)
+
+/* Output at beginning of assembler file. */
+/* The .file command should always begin the output. */
+
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) \
+ do { \
+ output_file_directive (FILE, main_input_filename); \
+ fprintf (FILE, "\t.version\t\"01.01\"\n"); \
+ } while (0)
+
+/* Define the register numbers to be used in Dwarf debugging information.
+ The SVR4 reference port C compiler uses the following register numbers
+ in its Dwarf output code:
+
+ 0 for %eax (gnu regno = 0)
+ 1 for %ecx (gnu regno = 2)
+ 2 for %edx (gnu regno = 1)
+ 3 for %ebx (gnu regno = 3)
+ 4 for %esp (gnu regno = 7)
+ 5 for %ebp (gnu regno = 6)
+ 6 for %esi (gnu regno = 4)
+ 7 for %edi (gnu regno = 5)
+
+ The following three DWARF register numbers are never generated by
+ the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
+ believes these numbers have these meanings.
+
+ 8 for %eip (no gnu equivalent)
+ 9 for %eflags (no gnu equivalent)
+ 10 for %trapno (no gnu equivalent)
+
+ It is not at all clear how we should number the FP stack registers
+ for the x86 architecture. If the version of SDB on x86/svr4 were
+ a bit less brain dead with respect to floating-point then we would
+ have a precedent to follow with respect to DWARF register numbers
+ for x86 FP registers, but the SDB on x86/svr4 is so completely
+ broken with respect to FP registers that it is hardly worth thinking
+ of it as something to strive for compatibility with.
+
+ The version of x86/svr4 SDB I have at the moment does (partially)
+ seem to believe that DWARF register number 11 is associated with
+ the x86 register %st(0), but that's about all. Higher DWARF
+ register numbers don't seem to be associated with anything in
+ particular, and even for DWARF regno 11, SDB only seems to under-
+ stand that it should say that a variable lives in %st(0) (when
+ asked via an `=' command) if we said it was in DWARF regno 11,
+ but SDB still prints garbage when asked for the value of the
+ variable in question (via a `/' command).
+
+ (Also note that the labels SDB prints for various FP stack regs
+ when doing an `x' command are all wrong.)
+
+ Note that these problems generally don't affect the native SVR4
+ C compiler because it doesn't allow the use of -O with -g and
+ because when it is *not* optimizing, it allocates a memory
+ location for each floating-point variable, and the memory
+ location is what gets described in the DWARF AT_location
+ attribute for the variable in question.
+
+ Regardless of the severe mental illness of the x86/svr4 SDB, we
+ do something sensible here and we use the following DWARF
+ register numbers. Note that these are all stack-top-relative
+ numbers.
+
+ 11 for %st(0) (gnu regno = 8)
+ 12 for %st(1) (gnu regno = 9)
+ 13 for %st(2) (gnu regno = 10)
+ 14 for %st(3) (gnu regno = 11)
+ 15 for %st(4) (gnu regno = 12)
+ 16 for %st(5) (gnu regno = 13)
+ 17 for %st(6) (gnu regno = 14)
+ 18 for %st(7) (gnu regno = 15)
+*/
+
+#undef DBX_REGISTER_NUMBER
+#define DBX_REGISTER_NUMBER(n) \
+((n) == 0 ? 0 \
+ : (n) == 1 ? 2 \
+ : (n) == 2 ? 1 \
+ : (n) == 3 ? 3 \
+ : (n) == 4 ? 6 \
+ : (n) == 5 ? 7 \
+ : (n) == 6 ? 5 \
+ : (n) == 7 ? 4 \
+ : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \
+ : (-1))
+
+/* The routine used to output sequences of byte values. We use a special
+ version of this for most svr4 targets because doing so makes the
+ generated assembly code more compact (and thus faster to assemble)
+ as well as more readable. Note that if we find subparts of the
+ character sequence which end with NUL (and which are shorter than
+ STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
+
+#undef ASM_OUTPUT_ASCII
+#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
+ do \
+ { \
+ register unsigned char *_ascii_bytes = (unsigned char *) (STR); \
+ register unsigned char *limit = _ascii_bytes + (LENGTH); \
+ register unsigned bytes_in_chunk = 0; \
+ for (; _ascii_bytes < limit; _ascii_bytes++) \
+ { \
+ register unsigned char *p; \
+ if (bytes_in_chunk >= 64) \
+ { \
+ fputc ('\n', (FILE)); \
+ bytes_in_chunk = 0; \
+ } \
+ for (p = _ascii_bytes; p < limit && *p != '\0'; p++) \
+ continue; \
+ if (p < limit && (p - _ascii_bytes) <= STRING_LIMIT) \
+ { \
+ if (bytes_in_chunk > 0) \
+ { \
+ fputc ('\n', (FILE)); \
+ bytes_in_chunk = 0; \
+ } \
+ ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes); \
+ _ascii_bytes = p; \
+ } \
+ else \
+ { \
+ if (bytes_in_chunk == 0) \
+ fprintf ((FILE), "\t.byte\t"); \
+ else \
+ fputc (',', (FILE)); \
+ fprintf ((FILE), "0x%02x", *_ascii_bytes); \
+ bytes_in_chunk += 5; \
+ } \
+ } \
+ if (bytes_in_chunk > 0) \
+ fprintf ((FILE), "\n"); \
+ } \
+ while (0)
+
+/* This is how to output an element of a case-vector that is relative.
+ This is only used for PIC code. See comments by the `casesi' insn in
+ i386.md for an explanation of the expression this outputs. */
+
+#undef ASM_OUTPUT_ADDR_DIFF_ELT
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
+ fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE)
+
+/* Indicate that jump tables go in the text section. This is
+ necessary when compiling PIC code. */
+
+#define JUMP_TABLES_IN_TEXT_SECTION
diff --git a/gnu/usr.bin/gcc/config/i386/rtems.h b/gnu/usr.bin/gcc/config/i386/rtems.h
new file mode 100644
index 00000000000..b31ceb9f799
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/rtems.h
@@ -0,0 +1,28 @@
+/* Definitions for rtems targeting an Intel i386 using coff.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Joel Sherrill (joel@OARcorp.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-coff.h"
+
+/* Specify predefined symbols in preprocessor. */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Di386 -Drtems -D__rtems__ \
+ -Asystem(rtems) -Acpu(i386) -Amachine(i386)"
diff --git a/gnu/usr.bin/gcc/config/i386/sco5.h b/gnu/usr.bin/gcc/config/i386/sco5.h
new file mode 100644
index 00000000000..5306000e2a0
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/sco5.h
@@ -0,0 +1,967 @@
+/* Definitions for Intel 386 running SCO Unix System V 3.2 Version 5.
+ Copyright (C) 1992, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Kean Johnston (hug@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 definitions */
+#include "i386/att.h" /* Use AT&T i386 assembler syntax */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (i386, SCO OpenServer 5 Syntax)");
+
+#undef LPREFIX
+#define LPREFIX ".L"
+
+#undef ALIGN_ASM_OP
+#define ALIGN_ASM_OP "\t.align"
+
+#undef ASCII_DATA_ASM_OP
+#define ASCII_DATA_ASM_OP "\t.ascii"
+
+#undef ASM_BYTE_OP
+#define ASM_BYTE_OP "\t.byte"
+
+#undef IDENT_ASM_OP
+#define IDENT_ASM_OP "\t.ident"
+
+#undef COMMON_ASM_OP
+#define COMMON_ASM_OP "\t.comm"
+
+#undef SET_ASM_OP
+#define SET_ASM_OP "\t.set"
+
+#undef LOCAL_ASM_OP
+#define LOCAL_ASM_OP "\t.local"
+
+#undef INT_ASM_OP
+#define INT_ASM_OP "\t.long"
+
+#undef ASM_SHORT
+#define ASM_SHORT "\t.value"
+
+#undef ASM_LONG
+#define ASM_LONG "\t.long"
+
+#undef ASM_DOUBLE
+#define ASM_DOUBLE "\t.double"
+
+#undef TYPE_ASM_OP
+#define TYPE_ASM_OP "\t.type"
+
+#undef SIZE_ASM_OP
+#define SIZE_ASM_OP "\t.size"
+
+#undef STRING_ASM_OP
+#define STRING_ASM_OP "\t.string"
+
+#undef SKIP_ASM_OP
+#define SKIP_ASM_OP "\t.zero"
+
+#undef GLOBAL_ASM_OP
+#define GLOBAL_ASM_OP "\t.globl"
+
+#undef EH_FRAME_SECTION_ASM_OP
+#define EH_FRAME_SECTION_ASM_OP_COFF "\t.section\t.ehfram, \"x\""
+#define EH_FRAME_SECTION_ASM_OP_ELF "\t.section\t.eh_frame, \"aw\""
+#define EH_FRAME_SECTION_ASM_OP \
+ ((TARGET_ELF) ? EH_FRAME_SECTION_ASM_OP_ELF : EH_FRAME_SECTION_ASM_OP_COFF)
+
+/* Avoid problems (long section names, forward assembler refs) with DWARF
+ exception unwinding when we're generating COFF */
+#define DWARF2_UNWIND_INFO ((TARGET_ELF) ? 1 : 0 )
+
+#undef CONST_SECTION_ASM_OP
+#define CONST_SECTION_ASM_OP_COFF "\t.section\t.rodata, \"x\""
+#define CONST_SECTION_ASM_OP_ELF "\t.section\t.rodata"
+#define CONST_SECTION_ASM_OP \
+ ((TARGET_ELF) ? CONST_SECTION_ASM_OP_ELF : CONST_SECTION_ASM_OP_COFF)
+
+#undef USE_CONST_SECTION
+#define USE_CONST_SECTION_ELF 1
+#define USE_CONST_SECTION_COFF 0
+#define USE_CONST_SECTION \
+ ((TARGET_ELF) ? USE_CONST_SECTION_ELF : USE_CONST_SECTION_COFF)
+
+#undef INIT_SECTION_ASM_OP
+#define INIT_SECTION_ASM_OP_ELF "\t.section\t.init"
+#define INIT_SECTION_ASM_OP_COFF "\t.section\t.init ,\"x\""
+#define INIT_SECTION_ASM_OP \
+ ((TARGET_ELF) ? INIT_SECTION_ASM_OP_ELF : INIT_SECTION_ASM_OP_COFF)
+
+#undef CTORS_SECTION_ASM_OP
+#define CTORS_SECTION_ASM_OP_ELF "\t.section\t.ctors,\"aw\""
+#define CTORS_SECTION_ASM_OP_COFF INIT_SECTION_ASM_OP_COFF
+#define CTORS_SECTION_ASM_OP \
+ ((TARGET_ELF) ? CTORS_SECTION_ASM_OP_ELF : CTORS_SECTION_ASM_OP_COFF)
+
+#undef DTORS_SECTION_ASM_OP
+#define DTORS_SECTION_ASM_OP_ELF "\t.section\t.dtors, \"aw\""
+#define DTORS_SECTION_ASM_OP_COFF FINI_SECTION_ASM_OP_COFF
+#define DTORS_SECTION_ASM_OP \
+ ((TARGET_ELF) ? DTORS_SECTION_ASM_OP_ELF : DTORS_SECTION_ASM_OP_COFF)
+
+#undef FINI_SECTION_ASM_OP
+#define FINI_SECTION_ASM_OP_ELF "\t.section\t.fini"
+#define FINI_SECTION_ASM_OP_COFF "\t.section\t.fini, \"x\""
+#define FINI_SECTION_ASM_OP \
+ ((TARGET_ELF) ? FINI_SECTION_ASM_OP_ELF : FINI_SECTION_ASM_OP_COFF)
+
+#undef BSS_SECTION_ASM_OP
+#define BSS_SECTION_ASM_OP "\t.data"
+
+#undef TEXT_SECTION_ASM_OP
+#define TEXT_SECTION_ASM_OP "\t.text"
+
+#undef DATA_SECTION_ASM_OP
+#define DATA_SECTION_ASM_OP "\t.data"
+
+#undef TYPE_OPERAND_FMT
+#define TYPE_OPERAND_FMT "@%s"
+
+#undef APPLY_RESULT_SIZE
+#define APPLY_RESULT_SIZE \
+(TARGET_ELF) ? size : 116
+
+#ifndef ASM_DECLARE_RESULT
+#define ASM_DECLARE_RESULT(FILE, RESULT)
+#endif
+
+#define SCO_DEFAULT_ASM_COFF(FILE,NAME) \
+do { \
+ ASM_OUTPUT_LABEL (FILE, NAME); \
+ } while (0)
+
+#undef ASM_DECLARE_FUNCTION_NAME
+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
+ do { \
+ if (TARGET_ELF) { \
+ fprintf (FILE, "%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); \
+ } else \
+ SCO_DEFAULT_ASM_COFF(FILE, NAME); \
+} while (0)
+
+#undef ASM_DECLARE_FUNCTION_SIZE
+#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
+ do { \
+ if (TARGET_ELF) { if (!flag_inhibit_size_directive) \
+ { \
+ fprintf (FILE, "%s\t ", SIZE_ASM_OP); \
+ assemble_name (FILE, (FNAME)); \
+ fprintf (FILE, ",.-"); \
+ assemble_name (FILE, (FNAME)); \
+ putc ('\n', FILE); \
+ } } \
+ } while (0)
+
+#undef ASM_DECLARE_OBJECT_NAME
+#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
+ do { \
+ if (TARGET_ELF) { \
+ fprintf (FILE, "%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, "%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); \
+ } else \
+ SCO_DEFAULT_ASM_COFF(FILE, NAME); \
+ } while (0)
+
+#undef ASM_FILE_START_1
+#define ASM_FILE_START_1(FILE)
+
+#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)
+
+#undef ASM_FILE_END
+#define ASM_FILE_END(FILE) \
+do { \
+ fprintf ((FILE), "%s\t\"GCC: (GNU) %s\"\n", \
+ IDENT_ASM_OP, version_string); \
+} while (0)
+
+#undef ASM_FINISH_DECLARE_OBJECT
+#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
+do { \
+ if (TARGET_ELF) { \
+ 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) \
+ { \
+ size_directive_output = 1; \
+ fprintf (FILE, "%s\t ", SIZE_ASM_OP); \
+ assemble_name (FILE, name); \
+ fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \
+ } \
+ } \
+} while (0)
+
+#undef ASM_GENERATE_INTERNAL_LABEL
+#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
+do { \
+ if (TARGET_ELF) \
+ sprintf (LABEL, "*.%s%d", (PREFIX), (NUM)); \
+ else \
+ sprintf (LABEL, ".%s%d", (PREFIX), (NUM)); \
+} while (0)
+
+#undef ASM_OUTPUT_ADDR_DIFF_ELT
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
+do { \
+ if (TARGET_ELF) \
+ fprintf (FILE, "%s _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", ASM_LONG, LPREFIX, VALUE); \
+ else \
+ fprintf (FILE, "\t.word %s%d-%s%d\n", LPREFIX,VALUE,LPREFIX,REL); \
+} while (0)
+
+#undef ASM_OUTPUT_ALIGNED_COMMON
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
+do { \
+ fprintf ((FILE), "%s\t", COMMON_ASM_OP); \
+ assemble_name ((FILE), (NAME)); \
+ if (TARGET_ELF) \
+ fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
+ else \
+ fprintf ((FILE), ",%u\n", (SIZE)); \
+} while (0)
+
+#undef ASM_OUTPUT_ALIGNED_LOCAL
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
+do { \
+ if (TARGET_ELF) { \
+ fprintf ((FILE), "%s\t", LOCAL_ASM_OP); \
+ assemble_name ((FILE), (NAME)); \
+ fprintf ((FILE), "\n"); \
+ ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \
+ } else { \
+ int align = exact_log2 (ALIGN); \
+ if (align > 2) align = 2; \
+ if (TARGET_SVR3_SHLIB) \
+ data_section (); \
+ else \
+ bss_section (); \
+ ASM_OUTPUT_ALIGN ((FILE), align == -1 ? 2 : align); \
+ fprintf ((FILE), "%s\t", "\t.lcomm"); \
+ assemble_name ((FILE), (NAME)); \
+ fprintf ((FILE), ",%u\n", (SIZE)); \
+ } \
+} while (0)
+
+/* A C statement (sans semicolon) to output to the stdio stream
+ FILE the assembler definition of uninitialized global DECL named
+ NAME whose size is SIZE bytes and alignment is ALIGN bytes.
+ Try to use asm_output_aligned_bss to implement this macro. */
+
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
+
+#undef ESCAPES
+#define ESCAPES \
+"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
+\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\
+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"
+
+#undef STRING_LIMIT
+#define STRING_LIMIT ((unsigned) 256)
+
+#undef ASM_OUTPUT_LIMITED_STRING
+#define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \
+ do \
+ { \
+ register unsigned char *_limited_str = (unsigned char *) (STR); \
+ register unsigned ch; \
+ fprintf ((FILE), "%s\t\"", STRING_ASM_OP); \
+ for (; ch = *_limited_str; _limited_str++) \
+ { \
+ register int escape; \
+ switch (escape = ESCAPES[ch]) \
+ { \
+ case 0: \
+ putc (ch, (FILE)); \
+ break; \
+ case 1: \
+ fprintf ((FILE), "\\%03o", ch); \
+ break; \
+ default: \
+ putc ('\\', (FILE)); \
+ putc (escape, (FILE)); \
+ break; \
+ } \
+ } \
+ fprintf ((FILE), "\"\n"); \
+ } \
+ while (0)
+
+
+#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), "%s\t", ASM_BYTE_OP); \
+ else \
+ fputc (',', (FILE)); \
+ fprintf ((FILE), "0x%02x", *_ascii_bytes); \
+ bytes_in_chunk += 5; \
+ } \
+ } \
+ if (bytes_in_chunk > 0) \
+ fprintf ((FILE), "\n"); \
+} while (0)
+
+/* Must use data section for relocatable constants when pic. */
+#undef SELECT_RTX_SECTION
+#define SELECT_RTX_SECTION(MODE,RTX) \
+{ \
+ if (TARGET_ELF) { \
+ if (flag_pic && symbolic_operand (RTX)) \
+ data_section (); \
+ else \
+ const_section (); \
+ } else \
+ readonly_data_section(); \
+}
+
+#undef ASM_OUTPUT_CASE_LABEL
+#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,JUMPTABLE) \
+do { \
+ if (TARGET_ELF) \
+ ASM_OUTPUT_ALIGN ((FILE), 2); \
+ ASM_OUTPUT_INTERNAL_LABEL((FILE),(PREFIX),(NUM)); \
+} while (0)
+
+
+#undef ASM_OUTPUT_CONSTRUCTOR
+#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
+do { \
+ if (TARGET_ELF) { \
+ ctors_section (); \
+ fprintf (FILE, "%s\t ", INT_ASM_OP); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, "\n"); \
+ } else { \
+ init_section (); \
+ fprintf (FILE, "\tpushl $"); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, "\n"); } \
+ } while (0)
+
+#undef ASM_OUTPUT_DESTRUCTOR
+#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
+do { \
+ if (TARGET_ELF) { \
+ dtors_section (); \
+ fprintf (FILE, "%s\t ", INT_ASM_OP); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, "\n"); \
+ } else { \
+ fini_section (); \
+ fprintf (FILE, "%s\t ", ASM_LONG); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, "\n"); } \
+ } while (0)
+
+
+#undef ASM_OUTPUT_DOUBLE
+#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
+do { \
+ long value[2]; \
+ REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), value); \
+ if (TARGET_ELF) { \
+ 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]); \
+ } \
+ } else { \
+ if (sizeof (int) == sizeof (long)) \
+ fprintf (FILE, "%s 0x%x,0x%x\n", ASM_LONG, value[0], value[1]); \
+ else \
+ fprintf (FILE, "%s 0x%lx,0x%lx\n", ASM_LONG,value[0],value[1]);} \
+} while (0)
+
+#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)
+
+#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 (TARGET_ELF) { \
+ if (sizeof (int) == sizeof (long)) \
+ { \
+ fprintf((FILE), "%s\t0x%x\n", ASM_LONG, l[0]); \
+ fprintf((FILE), "%s\t0x%x\n", ASM_LONG, l[1]); \
+ fprintf((FILE), "%s\t0x%x\n", ASM_LONG, l[2]); \
+ } \
+ else \
+ { \
+ fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, l[0]); \
+ fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, l[1]); \
+ fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, l[2]); \
+ } \
+ } else { \
+ 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)
+
+#undef ASM_OUTPUT_IDENT
+#define ASM_OUTPUT_IDENT(FILE, NAME) \
+ fprintf (FILE, "%s\t\"%s\"\n", IDENT_ASM_OP, NAME);
+
+#undef ASM_GLOBALIZE_LABEL
+#define ASM_GLOBALIZE_LABEL(FILE,NAME) \
+ (fprintf ((FILE), "%s ", GLOBAL_ASM_OP), assemble_name (FILE, NAME), fputs ("\n", FILE))
+
+#undef ASM_OUTPUT_EXTERNAL_LIBCALL
+#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
+ if (TARGET_ELF) ASM_GLOBALIZE_LABEL (FILE, XSTR (FUN, 0))
+
+#undef ASM_OUTPUT_INTERNAL_LABEL
+#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
+ fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
+
+/* The prefix to add to user-visible assembler symbols. */
+
+#undef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX ""
+
+#undef ASM_OUTPUT_SECTION_NAME
+#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
+do { \
+ char *snam = NAME ; \
+ if (strcmp(NAME, ".gcc_except_table") == 0) snam = ".gccexc" ; \
+ if (TARGET_ELF) \
+ fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, \
+ (DECL) && TREE_CODE (DECL) == FUNCTION_DECL ? "ax" : \
+ (DECL) && DECL_READONLY_SECTION (DECL, RELOC) ? "a" : "aw"); \
+ else \
+ fprintf (FILE, ".section\t%s,\"%s\"\n", snam, \
+ (DECL) && TREE_CODE (DECL) == FUNCTION_DECL ? "x" : \
+ (DECL) && DECL_READONLY_SECTION (DECL, RELOC) ? "a" : "w"); \
+} while (0)
+
+#undef ASM_OUTPUT_SKIP
+#define ASM_OUTPUT_SKIP(FILE,SIZE) \
+do { \
+ if (TARGET_ELF) \
+ fprintf (FILE, "%s\t%u\n", SKIP_ASM_OP, (SIZE)); \
+ else \
+ fprintf ((FILE), "%s\t.,.+%u\n", SET_ASM_OP, (SIZE)); \
+} while (0)
+
+
+#undef CTOR_LIST_BEGIN
+#define CTOR_LIST_BEGIN \
+do { \
+ asm (CTORS_SECTION_ASM_OP); \
+ if (TARGET_ELF) \
+ STATIC func_ptr __CTOR_LIST__[1] = { (func_ptr) (-1) }; \
+ else \
+ asm ("pushl $0"); \
+} while (0)
+
+#undef CTOR_LIST_END
+#define CTOR_LIST_END \
+do { \
+ if (TARGET_ELF) { \
+ asm (CTORS_SECTION_ASM_OP); \
+ STATIC func_ptr __CTOR_LIST__[1] = { (func_ptr) (0) }; \
+ } else { \
+ CTOR_LIST_BEGIN; \
+ } \
+} while (0)
+
+#undef DBX_BLOCKS_FUNCTION_RELATIVE
+#define DBX_BLOCKS_FUNCTION_RELATIVE 1
+
+#undef DBX_FUNCTION_FIRST
+#define DBX_FUNCTION_FIRST 1
+
+#undef DBX_REGISTER_NUMBER
+#define DBX_REGISTER_NUMBER(n) \
+((TARGET_ELF) ? \
+ ((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)) \
+ : \
+ ((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 DWARF_DEBUGGING_INFO
+#undef SDB_DEBUGGING_INFO
+#undef DBX_DEBUGGING_INFO
+#undef PREFERRED_DEBUGGING_TYPE
+
+#define DWARF_DEBUGGING_INFO 1
+#define SDB_DEBUGGING_INFO 1
+#define DBX_DEBUGGING_INFO 1
+#define PREFERRED_DEBUGGING_TYPE \
+ ((TARGET_ELF) ? DWARF_DEBUG: SDB_DEBUG)
+
+#undef EXTRA_SECTIONS
+#define EXTRA_SECTIONS in_const, in_init, in_fini, in_ctors, in_dtors
+
+#undef EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS \
+ CONST_SECTION_FUNCTION \
+ INIT_SECTION_FUNCTION \
+ FINI_SECTION_FUNCTION \
+ CTORS_SECTION_FUNCTION \
+ DTORS_SECTION_FUNCTION
+
+#undef CONST_SECTION_FUNCTION
+#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; \
+ } \
+}
+
+#undef FINI_SECTION_FUNCTION
+#define FINI_SECTION_FUNCTION \
+void \
+fini_section () \
+{ \
+ if ((!TARGET_ELF) && in_section != in_fini) \
+ { \
+ fprintf (asm_out_file, "%s\n", FINI_SECTION_ASM_OP); \
+ in_section = in_fini; \
+ } \
+}
+
+#undef INIT_SECTION_FUNCTION
+#define INIT_SECTION_FUNCTION \
+void \
+init_section () \
+{ \
+ if ((!TARGET_ELF) && in_section != in_init) \
+ { \
+ fprintf (asm_out_file, "%s\n", INIT_SECTION_ASM_OP); \
+ in_section = in_init; \
+ } \
+}
+
+#undef CTORS_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; \
+ } \
+}
+
+#undef DTORS_SECTION_FUNCTION
+#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; \
+ } \
+}
+
+#undef FRAME_POINTER_REQUIRED
+#define FRAME_POINTER_REQUIRED \
+ ((TARGET_ELF) ? 0 : \
+ (current_function_calls_setjmp || current_function_calls_longjmp))
+
+#undef JUMP_TABLES_IN_TEXT_SECTION
+#define JUMP_TABLES_IN_TEXT_SECTION 1
+
+#undef LOCAL_LABEL_PREFIX
+#define LOCAL_LABEL_PREFIX \
+ ((TARGET_ELF) ? "" : ".")
+
+#undef MD_EXEC_PREFIX
+#undef MD_STARTFILE_PREFIX
+#define MD_EXEC_PREFIX "/usr/ccs/bin/"
+#define MD_STARTFILE_PREFIX "/usr/ccs/lib/"
+
+#undef NON_SAVING_SETJMP
+#define NON_SAVING_SETJMP \
+ ((TARGET_ELF) ? 0 : \
+ (current_function_calls_setjmp && current_function_calls_longjmp))
+
+#undef NO_IMPLICIT_EXTERN_C
+#define NO_IMPLICIT_EXTERN_C 1
+
+/* JKJ FIXME - examine the ramifications of RETURN_IN_MEMORY and
+ RETURN_POPS_ARGS */
+
+#undef RETURN_POPS_ARGS
+#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \
+ ((TARGET_ELF) ? \
+ (i386_return_pops_args (FUNDECL, FUNTYPE, SIZE)) : \
+ (((FUNDECL) && (TREE_CODE (FUNDECL) == IDENTIFIER_NODE)) ? 0 \
+ : (TARGET_RTD \
+ && (TYPE_ARG_TYPES (FUNTYPE) == 0 \
+ || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \
+ == void_type_node))) ? (SIZE) \
+ : 0))
+
+#undef SELECT_SECTION
+#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 ((TARGET_ELF && 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 (); \
+}
+
+#undef SWITCH_TAKES_ARG
+#define SWITCH_TAKES_ARG(CHAR) \
+ (DEFAULT_SWITCH_TAKES_ARG(CHAR) \
+ || (CHAR) == 'h' \
+ || (CHAR) == 'R' \
+ || (CHAR) == 'Y' \
+ || (CHAR) == 'z')
+
+#undef WORD_SWITCH_TAKES_ARG
+#define WORD_SWITCH_TAKES_ARG(STR) \
+ (DEFAULT_WORD_SWITCH_TAKES_ARG (STR) \
+ && strcmp (STR, "Tdata") && strcmp (STR, "Ttext") \
+ && strcmp (STR, "Tbss"))
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT 0301
+
+#undef HANDLE_SYSV_PRAGMA
+#define HANDLE_SYSV_PRAGMA 1
+
+#undef SCCS_DIRECTIVE
+#define SCCS_DIRECTIVE 1
+
+/*
+ * Define sizes and types
+ */
+#undef SIZE_TYPE
+#undef PTRDIFF_TYPE
+#undef WCHAR_TYPE
+#undef WCHAR_TYPE_SIZE
+#undef LONG_DOUBLE_TYPE_SIZE
+#define LONG_DOUBLE_TYPE_SIZE 96
+#define SIZE_TYPE "unsigned int"
+#define PTRDIFF_TYPE "int"
+#define WCHAR_TYPE "long int"
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+/*
+ * New for multilib support. Set the default switches for multilib,
+ * which is -melf.
+ */
+#define MULTILIB_DEFAULTS { "melf" }
+
+
+/* Please note that these specs may look messy but they are required in
+ order to emulate the SCO Development system as closely as possible.
+ With SCO Open Server 5.0, you now get the linker and assembler free,
+ so that is what these specs are targeted for. These utilities are
+ very argument sensitive: a space in the wrong place breaks everything.
+ So RMS, please forgive this mess. It works.
+
+ Parameters which can be passed to gcc, and their SCO equivalents:
+ GCC Parameter SCO Equivalent
+ -ansi -a ansi
+ -posix -a posix
+ -Xpg4 -a xpg4
+ -Xpg4plus -a xpg4plus
+ -Xods30 -a ods30
+
+ As with SCO, the default is XPG4 plus mode. SCO also allows you to
+ specify a C dialect with -Xt, -Xa, -Xc, -Xk and -Xm. These are passed
+ on to the assembler and linker in the same way that the SCO compiler
+ does.
+
+ SCO also allows you to compile, link and generate either ELF or COFF
+ binaries. With gcc, unlike the SCO compiler, the default is ELF.
+ Specify -mcoff to gcc to produce elf binaries. -fpic will get the
+ assembler and linker to produce PIC code.
+*/
+
+/* Set up assembler flags for PIC and ELF compilations */
+#undef ASM_SPEC
+#define ASM_SPEC \
+ "-b %{!mcoff:elf}%{mcoff:coff \
+ %{static:%e-static not valid with -mcoff} \
+ %{shared:%e-shared not valid with -mcoff} \
+ %{symbolic:%e-symbolic not valid with -mcoff}} \
+ %{Ym,*} %{Yd,*} %{Wa,*:%*} \
+ %{!mcoff:-E%{Xa:a}%{!Xa:%{Xc:c}%{!Xc:%{Xk:k}%{!Xk:%{Xt:t}%{!Xt:a}}}},%{ansi:ansi}%{!ansi:%{posix:posix}%{!posix:%{Xpg4:xpg4}%{!Xpg4:%{Xpg4plus:XPG4PLUS}%{!Xpg4plus:%{Xods30:ods30}%{!Xods30:XPG4PLUS}}}}},ELF %{Qn:} %{!Qy:-Qn}}"
+
+/* Use crt1.o as a startup file and crtn.o as a closing file. */
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+ "%{!shared:\
+ %{!symbolic: \
+ %{pg:gcrt.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}}} \
+ %{ansi:values-Xc.o%s} \
+ %{!ansi: \
+ %{traditional:values-Xt.o%s} \
+ %{!traditional: \
+ %{Xa:values-Xa.o%s} \
+ %{!Xa:%{Xc:values-Xc.o%s} \
+ %{!Xc:%{Xk:values-Xk.o%s} \
+ %{!Xk:%{Xt:values-Xt.o%s} \
+ %{!Xt:values-Xa.o%s}}}}}} \
+ %{mcoff:crtbeginS.o%s} %{!mcoff:crtbegin.o%s}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+ "%{!mcoff:crtend.o%s} \
+ %{mcoff:crtendS.o%s} \
+ %{pg:gcrtn.o%s}%{!pg:crtn.o%s}"
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES \
+ "-Asystem(svr3)"
+
+/* You are in a maze of GCC specs ... all alike */
+
+#undef CPP_SPEC
+#define CPP_SPEC "%(cpp_cpu) %[cpp_cpu] \
+ %{fpic:%{mcoff:%e-fpic is not valid with -mcoff}} \
+ %{fPIC:%{mcoff:%e-fPIC is not valid with -mcoff}} \
+ -D__i386 -D__unix -D_SCO_DS=1 -D_M_I386 -D_M_XENIX -D_M_UNIX \
+ %{!Xods30:-D_STRICT_NAMES} \
+ %{!ansi:%{!posix:%{!Xods30:-D_SCO_XPG_VERS=4}}} \
+ %{ansi:-isystem include/ansi%s -isystem /usr/include/ansi -D_STRICT_ANSI} \
+ %{!ansi: \
+ %{posix:-isystem include/posix%s -isystem /usr/include/posix \
+ -D_POSIX_C_SOURCE=2 -D_POSIX_SOURCE=1} \
+ %{!posix:%{Xpg4:-isystem include/xpg4%s -isystem /usr/include/xpg4 \
+ -D_XOPEN_SOURCE=1} \
+ %{!Xpg4:-D_M_I86 -D_M_I86SM -D_M_INTERNAT -D_M_SDATA -D_M_STEXT \
+ -D_M_BITFIELDS -D_M_SYS5 -D_M_SYSV -D_M_SYSIII \
+ -D_M_WORDSWAP -Dunix -DM_I386 -DM_UNIX -DM_XENIX \
+ %{Xods30:-isystem include/ods_30_compat%s \
+ -isystem /usr/include/ods_30_compat \
+ -D_SCO_ODS_30 -DM_I86 -DM_I86SM -DM_SDATA -DM_STEXT \
+ -DM_BITFIELDS -DM_SYS5 -DM_SYSV -DM_INTERNAT -DM_SYSIII \
+ -DM_WORDSWAP}}}} \
+ %{scointl:-DM_INTERNAT -D_M_INTERNAT} \
+ %{traditional:-D_KR -D_SVID -D_NO_PROTOTYPE} \
+ %{!mcoff:-D_SCO_ELF} \
+ %{mcoff:-D_M_COFF -D_SCO_COFF} \
+ %{!mcoff:%{fpic:-D__PIC__ -D__pic__} \
+ %{fPIC:%{!fpic:-D__PIC__ -D__pic__}}} \
+ %{Xa:-D_SCO_C_DIALECT=1} \
+ %{!Xa:%{Xc:-D_SCO_C_DIALECT=3} \
+ %{!Xc:%{Xk:-D_SCO_C_DIALECT=4} \
+ %{!Xk:%{Xt:-D_SCO_C_DIALECT=2} \
+ %{!Xt:-D_SCO_C_DIALECT=1}}}} \
+ %{traditional:-traditional -D_KR -D_NO_PROTOTYPE}"
+
+#undef LINK_SPEC
+#define LINK_SPEC \
+ "-b %{!mcoff:elf}%{mcoff:coff \
+ %{static:%e-static not valid with -mcoff} \
+ %{shared:%e-shared not valid with -mcoff} \
+ %{symbolic:%e-symbolic not valid with -mcoff} \
+ %{fpic:%e-fpic not valid with -mcoff} \
+ %{fPIC:%e-fPIC not valid with -mcoff}} \
+ -R%{Xa:a}%{!Xa:%{Xc:c}%{!Xc:%{Xk:k}%{!Xk:%{Xt:t}%{!Xt:a}}}},%{ansi:ansi}%{!ansi:%{posix:posix}%{!posix:%{Xpg4:xpg4}%{!Xpg4:%{Xpg4plus:XPG4PLUS}%{!Xpg4plus:%{Xods30:ods30}%{!Xods30:XPG4PLUS}}}}},%{mcoff:COFF}%{!mcoff:ELF} \
+ %{Wl,*%*} %{YP,*} %{YL,*} %{YU,*} \
+ %{!YP,*:%{p:-YP,/usr/ccs/libp:/lib/libp:/usr/lib/libp:/usr/ccs/lib:/lib:/usr/lib} \
+ %{!p:-YP,/usr/ccs/lib:/lib:/usr/lib}} \
+ %{h*} %{static:-dn -Bstatic} %{shared:-G -dy %{!z*:-z text}} \
+ %{symbolic:-Bsymbolic -G -dy %{!z*:-z text}} %{z*} %{R*} %{Y*} \
+ %{G:-G} %{!mcoff:%{Qn:} %{!Qy:-Qn}}"
+
+/* The SCO COFF linker gets confused on the difference between "-ofoo"
+ and "-o foo". So we just always force a single space. */
+
+#define SWITCHES_NEED_SPACES "o"
+
+/* Library spec. If we are not building a shared library, provide the
+ standard libraries, as per the SCO compiler. */
+
+#undef LIB_SPEC
+#define LIB_SPEC \
+ "%{shared:pic/libgcc.a%s}%{!shared:%{!symbolic:-lcrypt -lgen -lc}}"
+
+#undef LIBGCC_SPEC
+#define LIBGCC_SPEC \
+ "%{!shared:-lgcc}"
+
+#define MASK_COFF 010000000000 /* Mask for elf generation */
+#define TARGET_COFF (target_flags & MASK_COFF)
+#define TARGET_ELF (!(target_flags & MASK_COFF))
+
+#undef SUBTARGET_SWITCHES
+#define SUBTARGET_SWITCHES \
+ { "coff", MASK_COFF }, \
+ { "elf", -MASK_COFF },
+
+#define NO_DOLLAR_IN_LABEL
+
+/*
+Here comes some major hackery to get the crt stuff to compile properly.
+Since we can (and do) compile for both COFF and ELF environments, we
+set things up accordingly, based on the pre-processor defines for ELF
+and COFF. This is insane, but then I guess having one compiler with a
+single back-end supporting two vastly different file format types is
+a little insane too. But it is not impossible and we get a useful
+compiler at the end of the day. Onward we go ...
+*/
+
+#if defined(CRT_BEGIN) || defined(CRT_END) || defined(IN_LIBGCC2)
+# undef OBJECT_FORMAT_ELF
+# undef HAVE_ATEXIT
+# undef INIT_SECTION_ASM_OP
+# undef FINI_SECTION_ASM_OP
+# undef CTORS_SECTION_ASM_OP
+# undef DTORS_SECTION_ASM_OP
+# undef EH_FRAME_SECTION_ASM_OP
+# undef CTOR_LIST_BEGIN
+# undef CTOR_LIST_END
+# undef DO_GLOBAL_CTORS_BODY
+
+# if defined (_SCO_ELF)
+# define OBJECT_FORMAT_ELF
+# define HAVE_ATEXIT
+# define INIT_SECTION_ASM_OP INIT_SECTION_ASM_OP_ELF
+# define FINI_SECTION_ASM_OP FINI_SECTION_ASM_OP_ELF
+# define DTORS_SECTION_ASM_OP DTORS_SECTION_ASM_OP_ELF
+# define CTORS_SECTION_ASM_OP CTORS_SECTION_ASM_OP_ELF
+# define EH_FRAME_SECTION_ASM_OP EH_FRAME_SECTION_ASM_OP_ELF
+# else /* ! _SCO_ELF */
+# define INIT_SECTION_ASM_OP INIT_SECTION_ASM_OP_COFF
+# define FINI_SECTION_ASM_OP FINI_SECTION_ASM_OP_COFF
+# define DTORS_SECTION_ASM_OP DTORS_SECTION_ASM_OP_COFF
+# define CTORS_SECTION_ASM_OP CTORS_SECTION_ASM_OP_COFF
+# define EH_FRAME_SECTION_ASM_OP ""
+# define CTOR_LIST_BEGIN asm (INIT_SECTION_ASM_OP); asm ("pushl $0")
+# define CTOR_LIST_END CTOR_LIST_BEGIN
+# define DO_GLOBAL_CTORS_BODY \
+do { \
+ func_ptr *p, *beg = alloca(0); \
+ for (p = beg; *p;) \
+ (*p++) (); \
+} while (0)
+# endif /* ! _SCO_ELF */
+#endif /* CRT_BEGIN !! CRT_END */
diff --git a/gnu/usr.bin/gcc/config/i386/sol2-gc1.asm b/gnu/usr.bin/gcc/config/i386/sol2-gc1.asm
new file mode 100644
index 00000000000..8983a672ac2
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/sol2-gc1.asm
@@ -0,0 +1,160 @@
+! gcrt1.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.
+
+! This is a modified crt1.s by J.W.Hawtin <J.W.Hawtin@lboro.ac.uk> 15/8/96,
+! to allow program profiling, by calling monstartup on entry and _mcleanup
+! on exit
+
+ .file "gcrt1.s"
+ .ident "GNU C gcrt1.s"
+ .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 $_mcleanup,%eax
+ testl %eax,%eax
+ je .L1
+ pushl $_mcleanup
+ 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
+
+! Start profiling
+
+ pushl %ebp
+ movl %esp,%ebp
+ pushl $_etext
+ pushl $_start
+ call monstartup
+ addl $8,%esp
+ popl %ebp
+
+! 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
diff --git a/gnu/usr.bin/gcc/config/i386/sol2dbg.h b/gnu/usr.bin/gcc/config/i386/sol2dbg.h
new file mode 100644
index 00000000000..9d09c8fd043
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/sol2dbg.h
@@ -0,0 +1,16 @@
+/* Target definitions for GNU compiler for Intel 80386 running Solaris
+ with gas and gdb.
+ This file is added into the directory .../gcc-2.../config/i386
+ Workability without "#undef DWARF_DEBUGGING_INFO" is not tested. */
+
+/* Use stabs instead of DWARF debug format. */
+#ifdef PREFERRED_DEBUGGING_TYPE
+#undef PREFERRED_DEBUGGING_TYPE
+#endif
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+#include "i386/sol2.h"
+
+#ifdef DWARF_DEBUGGING_INFO
+#undef DWARF_DEBUGGING_INFO
+#endif
diff --git a/gnu/usr.bin/gcc/config/i386/t-cygwin32 b/gnu/usr.bin/gcc/config/i386/t-cygwin32
new file mode 100644
index 00000000000..4be2477fbc9
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/t-cygwin32
@@ -0,0 +1,7 @@
+LIBGCC1 = libgcc1-asm.a
+CROSS_LIBGCC1 = libgcc1-asm.a
+LIB1ASMSRC = i386/cygwin32.asm
+LIB1ASMFUNCS = _chkstk
+
+winnt.o: $(srcdir)/config/i386/winnt.c
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/winnt.c
diff --git a/gnu/usr.bin/gcc/config/i386/t-dgux b/gnu/usr.bin/gcc/config/i386/t-dgux
new file mode 100644
index 00000000000..292331f22a9
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/t-dgux
@@ -0,0 +1,4 @@
+#
+# target makefile for dgux
+#
+EXTRA_PARTS=crtbegin.o crtend.o
diff --git a/gnu/usr.bin/gcc/config/i386/t-freebsd b/gnu/usr.bin/gcc/config/i386/t-freebsd
new file mode 100644
index 00000000000..5164669d1ac
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/t-freebsd
@@ -0,0 +1,5 @@
+# Don't run fixproto
+STMP_FIXPROTO =
+# Use only native include files
+USER_H = $(EXTRA_HEADERS) $(LANG_EXTRA_HEADERS)
+
diff --git a/gnu/usr.bin/gcc/config/i386/t-go32 b/gnu/usr.bin/gcc/config/i386/t-go32
new file mode 100644
index 00000000000..6160b7ec945
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/t-go32
@@ -0,0 +1,2 @@
+LIBGCC1 = libgcc1.null
+CROSS_LIBGCC1 = libgcc1.null
diff --git a/gnu/usr.bin/gcc/config/i386/t-osf b/gnu/usr.bin/gcc/config/i386/t-osf
new file mode 100644
index 00000000000..c996e0c9e77
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/t-osf
@@ -0,0 +1,2 @@
+# If compiling with the osf gcc, avoid sharing code.
+TCFLAGS = -pic-none
diff --git a/gnu/usr.bin/gcc/config/i386/t-sco5 b/gnu/usr.bin/gcc/config/i386/t-sco5
new file mode 100644
index 00000000000..fd3d6c63b8e
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/t-sco5
@@ -0,0 +1,16 @@
+# The pushl in CTOR initialization interferes with frame pointer elimination.
+CRTSTUFF_T_CFLAGS = -fPIC -fno-omit-frame-pointer
+CRTSTUFF_T_CFLAGS_S = -mcoff -fno-omit-frame-pointer
+
+#
+# I am still a little unsure of the multilib architecture. The following
+# 4 lines are based on advice from meissner@cygnus.com.
+#
+MULTILIB_OPTIONS = mcoff/fPIC
+MULTILIB_DIRNAMES = coff pic
+MULTILIB_EXCEPTIONS = *mcoff*/*fPIC*
+MULTILIB_MATCHES = fPIC=fpic
+MULTILIB_EXTRA_OPTS =
+
+LIBGCC=stmp-multilib
+INSTALL_LIBGCC=install-multilib
diff --git a/gnu/usr.bin/gcc/config/i386/x-cygwin32 b/gnu/usr.bin/gcc/config/i386/x-cygwin32
new file mode 100644
index 00000000000..5e796a0e916
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/x-cygwin32
@@ -0,0 +1,4 @@
+# Don't run fixproto
+STMP_FIXPROTO =
+# Don't need collect2
+USE_COLLECT2 =
diff --git a/gnu/usr.bin/gcc/config/i386/x-dgux b/gnu/usr.bin/gcc/config/i386/x-dgux
new file mode 100644
index 00000000000..322bfe3ae91
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/x-dgux
@@ -0,0 +1,11 @@
+#
+# host is ix86 running dgux
+#
+CC = /bin/gcc
+X_CFLAGS = -O -mstandard -mlegend
+BOOT_CFLAGS = -O2 -g -mstandard -mlegend $(CFLAGS)
+CLIB = -lw32
+RANLIB = true
+USER_H = $(EXTRA_HEADERS) $(LANG_EXTRA_HEADERS)
+STMP_FIXPROTO =
+
diff --git a/gnu/usr.bin/gcc/config/i386/x-sco5 b/gnu/usr.bin/gcc/config/i386/x-sco5
new file mode 100644
index 00000000000..276d74045ed
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/x-sco5
@@ -0,0 +1,10 @@
+RANLIB = :
+RANLIB_TEST = false
+CC = cc
+OLDCC = cc
+CCLIBFLAGS =
+# We avoid the ALLOCA in -lPW becuase it gives us an evil index()
+ALLOCA = alloca.o
+
+# See all the declarations.
+FIXPROTO_DEFINES = -D_XOPEN_SOURCE -D_POSIX_C_SOURCE=2
diff --git a/gnu/usr.bin/gcc/config/i386/xm-cygwin32.h b/gnu/usr.bin/gcc/config/i386/xm-cygwin32.h
new file mode 100644
index 00000000000..98327f24b1d
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/xm-cygwin32.h
@@ -0,0 +1,26 @@
+/* Configuration for GNU C-compiler for hosting on Windows NT.
+ using a unix style C library.
+ Copyright (C) 1995, 1996, 1997 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
+#define EXECUTABLE_SUFFIX ".exe"
+
+/* Even though we support "/", allow "\" since everybody tests both. */
+#define DIR_SEPARATOR '\\'
diff --git a/gnu/usr.bin/gcc/config/i386/xm-dgux.h b/gnu/usr.bin/gcc/config/i386/xm-dgux.h
new file mode 100644
index 00000000000..5bdb9be0ebb
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/xm-dgux.h
@@ -0,0 +1,12 @@
+
+/* Configuration for GCC for Intel i386 running DG/ux */
+
+/* looks just like sysv4 for now */
+
+#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
diff --git a/gnu/usr.bin/gcc/config/i386/xm-go32.h b/gnu/usr.bin/gcc/config/i386/xm-go32.h
new file mode 100644
index 00000000000..d8182132ac6
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/xm-go32.h
@@ -0,0 +1,28 @@
+/* Configuration for GNU C-compiler for Intel 80386 running GO32.
+ Copyright (C) 1988, 1996 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 __MSDOS__ 1
+
+#define NO_STAB_H
+
+#include "i386/xm-i386.h"
+
+/* Use semicolons to separate elements of a path. */
+#define PATH_SEPARATOR ';'
diff --git a/gnu/usr.bin/gcc/config/i386/xm-mingw32.h b/gnu/usr.bin/gcc/config/i386/xm-mingw32.h
new file mode 100644
index 00000000000..47356f568d1
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/xm-mingw32.h
@@ -0,0 +1,45 @@
+/* Configuration for GNU C-compiler for hosting on Windows32.
+ using GNU tools and the Windows32 API Library.
+ Copyright (C) 1997 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
+
+#ifndef USG
+#define USG 1
+#endif
+
+#ifndef ONLY_INT_FIELD
+#define ONLY_INT_FIELDS 1
+#endif
+
+#ifndef USE_PROTOTYPES
+#define USE_PROTOTYPES 1
+#endif
+
+#define NO_SYS_SIGLIST 1
+#define link(a,b) -1
+#define environ _environ
+
+/* Even though we support "/", allow "\" since everybody tests both. */
+#define DIR_SEPARATOR '\\'
+#define EXECUTABLE_SUFFIX ".exe"
+
+#undef PATH_SEPARATOR
+#define PATH_SEPARATOR ';'
diff --git a/gnu/usr.bin/gcc/config/i386/xm-sco5.h b/gnu/usr.bin/gcc/config/i386/xm-sco5.h
new file mode 100644
index 00000000000..99bc53c2bc5
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i386/xm-sco5.h
@@ -0,0 +1,18 @@
+/* Configuration for GCC for Intel i386 running SCO. */
+
+#include "i386/xm-sysv3.h"
+
+/* Big buffers improve performance. */
+
+#define IO_BUFFER_SIZE (0x8000 - 1024)
+/* OpenServer provides no sys_siglist,
+ but does offer the same data under another name. */
+#define sys_siglist _sys_siglist
+#undef SYS_SIGLIST_DECLARED
+#define SYS_SIGLIST_DECLARED
+
+/* If not compiled with GNU C, use the portable alloca. */
+#ifndef __GNUC__
+#define USE_C_ALLOCA
+#endif
+
diff --git a/gnu/usr.bin/gcc/config/i960/rtems.h b/gnu/usr.bin/gcc/config/i960/rtems.h
new file mode 100644
index 00000000000..714706859d9
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/i960/rtems.h
@@ -0,0 +1,28 @@
+/* Definitions for rtems targeting an Intel i960.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Joel Sherrill (joel@OARcorp.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 "i960/i960-coff.h"
+
+/* Specify predefined symbols in preprocessor. */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Di960 -Di80960 -DI960 -DI80960 -Drtems -D__rtems__ \
+ -Asystem(rtems) -Acpu(i960) -Amachine(i960)"
diff --git a/gnu/usr.bin/gcc/config/libgloss.h b/gnu/usr.bin/gcc/config/libgloss.h
new file mode 100644
index 00000000000..2f2ba569f4f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/libgloss.h
@@ -0,0 +1,35 @@
+/* libgloss.h -- operating system specific defines to be used when
+ targeting GCC for Libgloss supported targets.
+ Copyright (C) 1996 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 libgloss standard for crt0.s has the name based on the command line
+ option. */
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "%{!shared:%{pg:pgcrt0%O%s}%{!pg:%{p:pcrt0%O%s}%{!p:crt0%O%s}}}"
+
+/* This file used to force LINK_SPEC to be the null string, but that is not
+ correct. LINK_SPEC is used to pass machine specific arguments to the
+ linker and hence can not be redefined here. LINK_SPEC is never used to
+ specify startup files or libraries, so it should never conflict with
+ libgloss. */
+
+/* Don't set the target flags, this is done by the linker script */
+#undef LIB_SPEC
+#define LIB_SPEC ""
diff --git a/gnu/usr.bin/gcc/config/m32r/initfini.c b/gnu/usr.bin/gcc/config/m32r/initfini.c
new file mode 100644
index 00000000000..34ef5da962f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m32r/initfini.c
@@ -0,0 +1,169 @@
+/* .init/.fini section handling + C++ global constructor/destructor handling.
+ This file is based on crtstuff.c, sol2-crti.asm, sol2-crtn.asm.
+
+Copyright (C) 1996, 1997 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. */
+
+/* As a special exception, if you link this file 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. */
+
+/* Declare a pointer to void function type. */
+typedef void (*func_ptr) (void);
+
+#ifdef CRT_INIT
+
+/* NOTE: In order to be able to support SVR4 shared libraries, we arrange
+ to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
+ __DTOR_END__ } per root executable and also one set of these symbols
+ per shared library. So in any given whole process image, we may have
+ multiple definitions of each of these symbols. In order to prevent
+ these definitions from conflicting with one another, and in order to
+ ensure that the proper lists are used for the initialization/finalization
+ of each individual shared library (respectively), we give these symbols
+ only internal (i.e. `static') linkage, and we also make it a point to
+ refer to only the __CTOR_END__ symbol in crtfini.o and the __DTOR_LIST__
+ symbol in crtinit.o, where they are defined. */
+
+static func_ptr __CTOR_LIST__[1]
+ __attribute__ ((section (".ctors")))
+ = { (func_ptr) (-1) };
+
+static func_ptr __DTOR_LIST__[1]
+ __attribute__ ((section (".dtors")))
+ = { (func_ptr) (-1) };
+
+/* Run all the global destructors on exit from the program. */
+
+/* Some systems place the number of pointers in the first word of the
+ table. On SVR4 however, that word is -1. In all cases, the table is
+ null-terminated. On SVR4, we start from the beginning of the list and
+ invoke each per-compilation-unit destructor routine in order
+ until we find that null.
+
+ Note that this function MUST be static. There will be one of these
+ functions in each root executable and one in each shared library, but
+ although they all have the same code, each one is unique in that it
+ refers to one particular associated `__DTOR_LIST__' which belongs to the
+ same particular root executable or shared library file. */
+
+static void __do_global_dtors ()
+asm ("__do_global_dtors") __attribute__ ((section (".text")));
+
+static void
+__do_global_dtors ()
+{
+ func_ptr *p;
+
+ for (p = __DTOR_LIST__ + 1; *p; p++)
+ (*p) ();
+}
+
+/* .init section start.
+ This must appear at the start of the .init section. */
+
+asm ("
+ .section .init,\"ax\",@progbits
+ .balign 4
+ .global __init
+__init:
+ push fp
+ push lr
+ mv fp,sp
+ ld24 r0,#__fini
+ bl atexit
+ .fillinsn
+");
+
+/* .fini section start.
+ This must appear at the start of the .init section. */
+
+asm ("
+ .section .fini,\"ax\",@progbits
+ .balign 4
+ .global __fini
+__fini:
+ push fp
+ push lr
+ mv fp,sp
+ bl __do_global_dtors
+ .fillinsn
+");
+
+#endif /* CRT_INIT */
+
+#ifdef CRT_FINI
+
+/* Put a word containing zero at the end of each of our two lists of function
+ addresses. Note that the words defined here go into the .ctors and .dtors
+ sections of the crtend.o file, and since that file is always linked in
+ last, these words naturally end up at the very ends of the two lists
+ contained in these two sections. */
+
+static func_ptr __CTOR_END__[1]
+ __attribute__ ((section (".ctors")))
+ = { (func_ptr) 0 };
+
+static func_ptr __DTOR_END__[1]
+ __attribute__ ((section (".dtors")))
+ = { (func_ptr) 0 };
+
+/* Run all global constructors for the program.
+ Note that they are run in reverse order. */
+
+static void __do_global_ctors ()
+asm ("__do_global_ctors") __attribute__ ((section (".text")));
+
+static void
+__do_global_ctors ()
+{
+ func_ptr *p;
+
+ for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
+ (*p) ();
+}
+
+/* .init section end.
+ This must live at the end of the .init section. */
+
+asm ("
+ .section .init,\"ax\",@progbits
+ bl __do_global_ctors
+ mv sp,fp
+ pop lr
+ pop fp
+ jmp lr
+ .fillinsn
+");
+
+/* .fini section end.
+ This must live at the end of the .fini section. */
+
+asm ("
+ .section .fini,\"ax\",@progbits
+ mv sp,fp
+ pop lr
+ pop fp
+ jmp lr
+ .fillinsn
+");
+
+#endif /* CRT_FINI */
diff --git a/gnu/usr.bin/gcc/config/m32r/m32r.c b/gnu/usr.bin/gcc/config/m32r/m32r.c
new file mode 100644
index 00000000000..48504a06e14
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m32r/m32r.c
@@ -0,0 +1,1835 @@
+/* Subroutines used for code generation on the Mitsubishi M32R cpu.
+ Copyright (C) 1996, 1997 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.h"
+#include <stdio.h>
+#include "tree.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 "flags.h"
+#include "expr.h"
+#include "recog.h"
+
+/* Save the operands last given to a compare for use when we
+ generate a scc or bcc insn. */
+rtx m32r_compare_op0, m32r_compare_op1;
+
+/* Array of valid operand punctuation characters. */
+char m32r_punct_chars[256];
+
+static void init_reg_tables ();
+
+/* Selected code model. */
+char *m32r_model_string = M32R_MODEL_DEFAULT;
+enum m32r_model m32r_model;
+
+/* Selected SDA support. */
+char *m32r_sdata_string = M32R_SDATA_DEFAULT;
+enum m32r_sdata m32r_sdata;
+
+/* Called by OVERRIDE_OPTIONS to initialize various things. */
+
+void
+m32r_init ()
+{
+ init_reg_tables ();
+
+ /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
+ memset (m32r_punct_chars, 0, sizeof (m32r_punct_chars));
+ m32r_punct_chars['#'] = 1;
+ m32r_punct_chars['@'] = 1; /* ??? no longer used */
+
+ /* Provide default value if not specified. */
+ if (!g_switch_set)
+ g_switch_value = SDATA_DEFAULT_SIZE;
+
+ if (strcmp (m32r_model_string, "small") == 0)
+ m32r_model = M32R_MODEL_SMALL;
+ else if (strcmp (m32r_model_string, "medium") == 0)
+ m32r_model = M32R_MODEL_MEDIUM;
+ else if (strcmp (m32r_model_string, "large") == 0)
+ m32r_model = M32R_MODEL_LARGE;
+ else
+ error ("bad value (%s) for -mmodel switch", m32r_model_string);
+
+ if (strcmp (m32r_sdata_string, "none") == 0)
+ m32r_sdata = M32R_SDATA_NONE;
+ else if (strcmp (m32r_sdata_string, "sdata") == 0)
+ m32r_sdata = M32R_SDATA_SDATA;
+ else if (strcmp (m32r_sdata_string, "use") == 0)
+ m32r_sdata = M32R_SDATA_USE;
+ else
+ error ("bad value (%s) for -msdata switch", m32r_sdata_string);
+}
+
+/* Vectors to keep interesting information about registers where it can easily
+ be got. We use to use the actual mode value as the bit number, but there
+ is (or may be) more than 32 modes now. Instead we use two tables: one
+ indexed by hard register number, and one indexed by mode. */
+
+/* The purpose of m32r_mode_class is to shrink the range of modes so that
+ they all fit (as bit numbers) in a 32 bit word (again). Each real mode is
+ mapped into one m32r_mode_class mode. */
+
+enum m32r_mode_class {
+ C_MODE,
+ S_MODE, D_MODE, T_MODE, O_MODE,
+ SF_MODE, DF_MODE, TF_MODE, OF_MODE
+};
+
+/* Modes for condition codes. */
+#define C_MODES (1 << (int) C_MODE)
+
+/* Modes for single-word and smaller quantities. */
+#define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
+
+/* Modes for double-word and smaller quantities. */
+#define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
+
+/* Modes for quad-word and smaller quantities. */
+#define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
+
+/* Value is 1 if register/mode pair is acceptable on arc. */
+
+unsigned int m32r_hard_regno_mode_ok[FIRST_PSEUDO_REGISTER] = {
+ T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
+ T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, S_MODES, S_MODES, S_MODES,
+ S_MODES, C_MODES
+};
+
+unsigned int m32r_mode_class [NUM_MACHINE_MODES];
+
+enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER];
+
+static void
+init_reg_tables ()
+{
+ int i;
+
+ for (i = 0; i < NUM_MACHINE_MODES; i++)
+ {
+ switch (GET_MODE_CLASS (i))
+ {
+ case MODE_INT:
+ case MODE_PARTIAL_INT:
+ case MODE_COMPLEX_INT:
+ if (GET_MODE_SIZE (i) <= 4)
+ m32r_mode_class[i] = 1 << (int) S_MODE;
+ else if (GET_MODE_SIZE (i) == 8)
+ m32r_mode_class[i] = 1 << (int) D_MODE;
+ else if (GET_MODE_SIZE (i) == 16)
+ m32r_mode_class[i] = 1 << (int) T_MODE;
+ else if (GET_MODE_SIZE (i) == 32)
+ m32r_mode_class[i] = 1 << (int) O_MODE;
+ else
+ m32r_mode_class[i] = 0;
+ break;
+ case MODE_FLOAT:
+ case MODE_COMPLEX_FLOAT:
+ if (GET_MODE_SIZE (i) <= 4)
+ m32r_mode_class[i] = 1 << (int) SF_MODE;
+ else if (GET_MODE_SIZE (i) == 8)
+ m32r_mode_class[i] = 1 << (int) DF_MODE;
+ else if (GET_MODE_SIZE (i) == 16)
+ m32r_mode_class[i] = 1 << (int) TF_MODE;
+ else if (GET_MODE_SIZE (i) == 32)
+ m32r_mode_class[i] = 1 << (int) OF_MODE;
+ else
+ m32r_mode_class[i] = 0;
+ break;
+ case MODE_CC:
+ default:
+ /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
+ we must explicitly check for them here. */
+ if (i == (int) CCmode)
+ m32r_mode_class[i] = 1 << (int) C_MODE;
+ else
+ m32r_mode_class[i] = 0;
+ break;
+ }
+ }
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ {
+ if (GPR_P (i))
+ m32r_regno_reg_class[i] = GENERAL_REGS;
+ else if (i == ARG_POINTER_REGNUM)
+ m32r_regno_reg_class[i] = GENERAL_REGS;
+ else
+ m32r_regno_reg_class[i] = NO_REGS;
+ }
+}
+
+/* M32R specific attribute support.
+
+ interrupt - for interrupt functions
+
+ model - select code model used to access object
+
+ small: addresses use 24 bits, use bl to make calls
+ medium: addresses use 32 bits, use bl to make calls
+ large: addresses use 32 bits, use seth/add3/jl to make calls
+
+ Grep for MODEL in m32r.h for more info.
+*/
+
+/* Return nonzero if IDENTIFIER is a valid decl attribute. */
+
+int
+m32r_valid_machine_decl_attribute (type, attributes, identifier, args)
+ tree type;
+ tree attributes;
+ tree identifier;
+ tree args;
+{
+ static tree interrupt_ident, model_ident;
+ static tree small_ident, medium_ident, large_ident;
+
+ if (interrupt_ident == 0)
+ {
+ interrupt_ident = get_identifier ("__interrupt__");
+ model_ident = get_identifier ("__model__");
+ small_ident = get_identifier ("__small__");
+ medium_ident = get_identifier ("__medium__");
+ large_ident = get_identifier ("__large__");
+ }
+
+ if (identifier == interrupt_ident
+ && list_length (args) == 0)
+ return 1;
+
+ if (identifier == model_ident
+ && list_length (args) == 1
+ && (TREE_VALUE (args) == small_ident
+ || TREE_VALUE (args) == medium_ident
+ || TREE_VALUE (args) == large_ident))
+ return 1;
+
+ return 0;
+}
+
+/* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
+ and two if they are nearly compatible (which causes a warning to be
+ generated). */
+
+int
+m32r_comp_type_attributes (type1, type2)
+ tree type1, type2;
+{
+ return 1;
+}
+
+/* Set the default attributes for TYPE. */
+
+void
+m32r_set_default_type_attributes (type)
+ tree type;
+{
+}
+
+/* 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. */
+
+void
+m32r_select_section (decl, reloc)
+ tree decl;
+ int reloc;
+{
+ if (TREE_CODE (decl) == STRING_CST)
+ {
+ if (! flag_writable_strings)
+ const_section ();
+ else
+ data_section ();
+ }
+ else if (TREE_CODE (decl) == VAR_DECL)
+ {
+ if (SDATA_NAME_P (XSTR (XEXP (DECL_RTL (decl), 0), 0)))
+ sdata_section ();
+ else if ((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 ();
+}
+
+/* Encode section information of DECL, which is either a VAR_DECL,
+ FUNCTION_DECL, STRING_CST, CONSTRUCTOR, or ???.
+
+ For the M32R we want to record:
+
+ - whether the object lives in .sdata/.sbss.
+ objects living in .sdata/.sbss are prefixed with SDATA_FLAG_CHAR
+
+ - what code model should be used to access the object
+ small: recorded with no flag - for space efficiency since they'll
+ be the most common
+ medium: prefixed with MEDIUM_FLAG_CHAR
+ large: prefixed with LARGE_FLAG_CHAR
+*/
+
+void
+m32r_encode_section_info (decl)
+ tree decl;
+{
+ char prefix = 0;
+ tree model = 0;
+
+ switch (TREE_CODE (decl))
+ {
+ case VAR_DECL :
+ case FUNCTION_DECL :
+ model = lookup_attribute ("model", DECL_MACHINE_ATTRIBUTES (decl));
+ break;
+ case STRING_CST :
+ case CONSTRUCTOR :
+ /* ??? document all others that can appear here */
+ default :
+ return;
+ }
+
+ /* Only mark the object as being small data area addressable if
+ it hasn't been explicitly marked with a code model.
+
+ The user can explicitly put an object in the small data area with the
+ section attribute. If the object is in sdata/sbss and marked with a
+ code model do both [put the object in .sdata and mark it as being
+ addressed with a specific code model - don't mark it as being addressed
+ with an SDA reloc though]. This is ok and might be useful at times. If
+ the object doesn't fit the linker will give an error. */
+
+ if (! model)
+ {
+ if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd'
+ && DECL_SECTION_NAME (decl) != NULL_TREE)
+ {
+ char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+ if (! strcmp (name, ".sdata") || ! strcmp (name, ".sbss"))
+ {
+#if 0 /* ??? There's no reason to disallow this, is there? */
+ if (TREE_READONLY (decl))
+ error_with_decl (decl, "const objects cannot go in .sdata/.sbss");
+#endif
+ prefix = SDATA_FLAG_CHAR;
+ }
+ }
+ else
+ {
+ if (TREE_CODE (decl) == VAR_DECL
+ && ! TREE_READONLY (decl)
+ && ! TARGET_SDATA_NONE)
+ {
+ int size = int_size_in_bytes (TREE_TYPE (decl));
+
+ if (size > 0 && size <= g_switch_value)
+ prefix = SDATA_FLAG_CHAR;
+ }
+ }
+ }
+
+ /* If data area not decided yet, check for a code model. */
+ if (prefix == 0)
+ {
+ if (model)
+ {
+ if (TREE_VALUE (TREE_VALUE (model)) == get_identifier ("__small__"))
+ ; /* don't mark the symbol specially */
+ else if (TREE_VALUE (TREE_VALUE (model)) == get_identifier ("__medium__"))
+ prefix = MEDIUM_FLAG_CHAR;
+ else if (TREE_VALUE (TREE_VALUE (model)) == get_identifier ("__large__"))
+ prefix = LARGE_FLAG_CHAR;
+ else
+ abort (); /* shouldn't happen */
+ }
+ else
+ {
+ if (TARGET_MODEL_SMALL)
+ ; /* don't mark the symbol specially */
+ else if (TARGET_MODEL_MEDIUM)
+ prefix = MEDIUM_FLAG_CHAR;
+ else if (TARGET_MODEL_LARGE)
+ prefix = LARGE_FLAG_CHAR;
+ else
+ abort (); /* shouldn't happen */
+ }
+ }
+
+ if (prefix != 0)
+ {
+ rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
+ ? TREE_CST_RTL (decl) : DECL_RTL (decl));
+ char *str = XSTR (XEXP (rtl, 0), 0);
+ int len = strlen (str);
+ char *newstr = savealloc (len + 2);
+ strcpy (newstr + 1, str);
+ *newstr = prefix;
+ XSTR (XEXP (rtl, 0), 0) = newstr;
+ }
+}
+
+/* Do anything needed before RTL is emitted for each function. */
+
+void
+m32r_init_expanders ()
+{
+ /* ??? At one point there was code here. The function is left in
+ to make it easy to experiment. */
+}
+
+/* Acceptable arguments to the call insn. */
+
+int
+call_address_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ return (symbolic_operand (op, mode)
+ || (GET_CODE (op) == CONST_INT && LEGITIMATE_CONSTANT_P (op))
+ || (GET_CODE (op) == REG));
+}
+
+int
+call_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != MEM)
+ return 0;
+ op = XEXP (op, 0);
+ return call_address_operand (op, mode);
+}
+
+/* Returns 1 if OP is a symbol reference. */
+
+int
+symbolic_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ switch (GET_CODE (op))
+ {
+ case SYMBOL_REF:
+ case LABEL_REF:
+ case CONST :
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* Return truth value of statement that OP is a symbolic memory
+ operand of mode MODE. */
+
+int
+symbolic_memory_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+ if (GET_CODE (op) != MEM)
+ return 0;
+ op = XEXP (op, 0);
+ return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
+ || GET_CODE (op) == LABEL_REF);
+}
+
+/* Return 1 if OP is a reference to an object in .sdata/.sbss. */
+
+int
+small_data_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (! TARGET_SDATA_USE)
+ return 0;
+
+ if (GET_CODE (op) == SYMBOL_REF)
+ return SDATA_NAME_P (XSTR (op, 0));
+
+ if (GET_CODE (op) == CONST
+ && GET_CODE (XEXP (op, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
+ && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
+ && INT16_P (INTVAL (XEXP (XEXP (op, 0), 1))))
+ return SDATA_NAME_P (XSTR (XEXP (XEXP (op, 0), 0), 0));
+
+ return 0;
+}
+
+/* Return 1 if OP is a symbol that can use 24 bit addressing. */
+
+int
+addr24_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == LABEL_REF)
+ return TARGET_ADDR24;
+
+ if (GET_CODE (op) == SYMBOL_REF)
+ return (SMALL_NAME_P (XSTR (op, 0))
+ || (TARGET_ADDR24
+ && (CONSTANT_POOL_ADDRESS_P (op)
+ || LIT_NAME_P (XSTR (op, 0)))));
+
+ if (GET_CODE (op) == CONST
+ && GET_CODE (XEXP (op, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
+ && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
+ && UINT24_P (INTVAL (XEXP (XEXP (op, 0), 1))))
+ {
+ rtx sym = XEXP (XEXP (op, 0), 0);
+ return (SMALL_NAME_P (XSTR (sym, 0))
+ || (TARGET_ADDR24
+ && (CONSTANT_POOL_ADDRESS_P (op)
+ || LIT_NAME_P (XSTR (op, 0)))));
+ }
+
+ return 0;
+}
+
+/* Return 1 if OP is a symbol that needs 32 bit addressing. */
+
+int
+addr32_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == LABEL_REF)
+ return TARGET_ADDR32;
+
+ if (GET_CODE (op) == SYMBOL_REF)
+ return (! addr24_operand (op)
+ && ! small_data_operand (op));
+
+ if (GET_CODE (op) == CONST
+ && GET_CODE (XEXP (op, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
+ && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
+ {
+ return (! addr24_operand (op)
+ && ! small_data_operand (op));
+ }
+
+ return 0;
+}
+
+/* Return 1 if OP is a function that can be called with the `bl' insn. */
+
+int
+call26_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == SYMBOL_REF)
+ return ! LARGE_NAME_P (XSTR (op, 0));
+
+ return TARGET_CALL26;
+}
+
+/* Return 1 if OP is a function that must be called with 32 bit addressing. */
+
+int
+call32_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ return ! call26_operand (op, mode);
+}
+
+/* Returns 1 if OP is an acceptable operand for seth/add3. */
+
+int
+seth_add3_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == SYMBOL_REF
+ || GET_CODE (op) == LABEL_REF)
+ return 1;
+
+ if (GET_CODE (op) == CONST
+ && GET_CODE (XEXP (op, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
+ && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
+ && INT16_P (INTVAL (XEXP (XEXP (op, 0), 1))))
+ return 1;
+
+ return 0;
+}
+
+/* Return true if OP is a signed 8 bit immediate value. */
+
+int
+int8_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ return INT8_P (INTVAL (op));
+}
+
+/* Return true if OP is a signed 16 bit immediate value. */
+
+int
+int16_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ return INT16_P (INTVAL (op));
+}
+
+/* Return true if OP is a signed 16 bit immediate value
+ useful in comparisons. */
+
+int
+cmp_int16_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ return CMP_INT16_P (INTVAL (op));
+}
+
+/* Return true if OP is an unsigned 16 bit immediate value. */
+
+int
+uint16_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ return UINT16_P (INTVAL (op));
+}
+
+/* Return true if OP is an unsigned 24 bit immediate value. */
+
+int
+uint24_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ return UINT24_P (INTVAL (op));
+}
+
+/* Return true if OP is a register or signed 8 bit value. */
+
+int
+reg_or_int8_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+ return register_operand (op, mode);
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ return INT8_P (INTVAL (op));
+}
+
+/* Return true if OP is a register or signed 8 bit value. */
+
+int
+reg_or_int16_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+ return register_operand (op, mode);
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ return INT16_P (INTVAL (op));
+}
+
+/* Return true if OP is a register or signed 8 bit value. */
+
+int
+reg_or_uint16_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+ return register_operand (op, mode);
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ return UINT16_P (INTVAL (op));
+}
+
+/* Return true if OP is a register or signed 16 bit value for compares. */
+
+int
+reg_or_cmp_int16_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+ return register_operand (op, mode);
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ return CMP_INT16_P (INTVAL (op));
+}
+
+/* Return true if OP is a const_int requiring two instructions to load. */
+
+int
+two_insn_const_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ if (INT16_P (INTVAL (op))
+ || UINT24_P (INTVAL (op))
+ || UPPER16_P (INTVAL (op)))
+ return 0;
+ return 1;
+}
+
+/* Return true if OP is an acceptable argument for a single word
+ move source. */
+
+int
+move_src_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ switch (GET_CODE (op))
+ {
+ case SYMBOL_REF :
+ case CONST :
+ return addr24_operand (op, mode);
+ case CONST_INT :
+ /* ??? We allow more cse opportunities if we only allow constants
+ loadable with one insn, and split the rest into two. The instances
+ where this would help should be rare and the current way is
+ simpler. */
+ return INT32_P (INTVAL (op));
+ case LABEL_REF :
+ return TARGET_ADDR24;
+ case CONST_DOUBLE :
+ if (mode == SFmode)
+ return 1;
+ else if (mode == SImode)
+ {
+ /* Large unsigned constants are represented as const_double's. */
+ unsigned HOST_WIDE_INT low, high;
+
+ low = CONST_DOUBLE_LOW (op);
+ high = CONST_DOUBLE_HIGH (op);
+ return high == 0 && low <= 0xffffffff;
+ }
+ else
+ return 0;
+ case REG :
+ return register_operand (op, mode);
+ case SUBREG :
+ /* (subreg (mem ...) ...) can occur here if the inner part was once a
+ pseudo-reg and is now a stack slot. */
+ if (GET_CODE (SUBREG_REG (op)) == MEM)
+ return address_operand (XEXP (SUBREG_REG (op), 0), mode);
+ else
+ return register_operand (op, mode);
+ case MEM :
+ return address_operand (XEXP (op, 0), mode);
+ default :
+ return 0;
+ }
+}
+
+/* Return true if OP is an acceptable argument for a double word
+ move source. */
+
+int
+move_double_src_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ switch (GET_CODE (op))
+ {
+ case CONST_INT :
+ case CONST_DOUBLE :
+ if (mode == DFmode)
+ return easy_df_const (op);
+ else
+ return easy_di_const (op);
+ case REG :
+ return register_operand (op, mode);
+ case SUBREG :
+ /* (subreg (mem ...) ...) can occur here if the inner part was once a
+ pseudo-reg and is now a stack slot. */
+ if (GET_CODE (SUBREG_REG (op)) == MEM)
+ return move_double_src_operand (SUBREG_REG (op), mode);
+ else
+ return register_operand (op, mode);
+ case MEM :
+ /* Disallow auto inc/dec for now. */
+ if (GET_CODE (XEXP (op, 0)) == PRE_DEC
+ || GET_CODE (XEXP (op, 0)) == PRE_INC)
+ return 0;
+ return address_operand (XEXP (op, 0), mode);
+ default :
+ return 0;
+ }
+}
+
+/* Return true if OP is an acceptable argument for a move destination. */
+
+int
+move_dest_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ switch (GET_CODE (op))
+ {
+ case REG :
+ return register_operand (op, mode);
+ case SUBREG :
+ /* (subreg (mem ...) ...) can occur here if the inner part was once a
+ pseudo-reg and is now a stack slot. */
+ if (GET_CODE (SUBREG_REG (op)) == MEM)
+ return address_operand (XEXP (SUBREG_REG (op), 0), mode);
+ else
+ return register_operand (op, mode);
+ case MEM :
+ return address_operand (XEXP (op, 0), mode);
+ default :
+ return 0;
+ }
+}
+
+/* Return 1 if OP is a DImode const we want to handle inline.
+ This must match the code in the movdi pattern.
+ It is used by the 'G' CONST_DOUBLE_OK_FOR_LETTER. */
+
+int
+easy_di_const (op)
+ rtx op;
+{
+ rtx high_rtx, low_rtx;
+ HOST_WIDE_INT high, low;
+
+ split_double (op, &high_rtx, &low_rtx);
+ high = INTVAL (high_rtx);
+ low = INTVAL (low_rtx);
+ /* Pick constants loadable with 2 16 bit `ldi' insns. */
+ if (high >= -128 && high <= 127
+ && low >= -128 && low <= 127)
+ return 1;
+ return 0;
+}
+
+/* Return 1 if OP is a DFmode const we want to handle inline.
+ This must match the code in the movdf pattern.
+ It is used by the 'H' CONST_DOUBLE_OK_FOR_LETTER. */
+
+int
+easy_df_const (op)
+ rtx op;
+{
+ REAL_VALUE_TYPE r;
+ long l[2];
+
+ REAL_VALUE_FROM_CONST_DOUBLE (r, op);
+ REAL_VALUE_TO_TARGET_DOUBLE (r, l);
+ if (l[0] == 0 && l[1] == 0)
+ return 1;
+ if ((l[0] & 0xffff) == 0 && l[1] == 0)
+ return 1;
+ return 0;
+}
+
+/* Return 1 if OP is an EQ or NE comparison operator. */
+
+int
+eqne_comparison_operator (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ enum rtx_code code = GET_CODE (op);
+
+ if (GET_RTX_CLASS (code) != '<')
+ return 0;
+ return (code == EQ || code == NE);
+}
+
+/* Return 1 if OP is a signed comparison operator. */
+
+int
+signed_comparison_operator (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ enum rtx_code code = GET_CODE (op);
+
+ if (GET_RTX_CLASS (code) != '<')
+ return 0;
+ return (code == EQ || code == NE
+ || code == LT || code == LE || code == GT || code == GE);
+}
+
+/* Return 1 if OP is (mem (reg ...)).
+ This is used in insn length calcs. */
+
+int
+memreg_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == REG;
+}
+
+/* Comparisons. */
+
+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
+ return the mode to be used for the comparison. */
+
+enum machine_mode
+m32r_select_cc_mode (op, x, y)
+ enum rtx_code op;
+ rtx x, y;
+{
+ return CCmode;
+}
+
+/* X and Y are two things to compare using CODE. Emit the compare insn and
+ return the rtx for compare [arg0 of the if_then_else]. */
+
+rtx
+gen_compare (code, x, y)
+ enum rtx_code code;
+ rtx x, y;
+{
+ enum machine_mode mode = SELECT_CC_MODE (code, x, y);
+ enum rtx_code compare_code, branch_code;
+ rtx cc_reg = gen_rtx (REG, mode, CARRY_REGNUM);
+ int swap_p = 0;
+
+ switch (code)
+ {
+ case EQ: compare_code = EQ; branch_code = NE; break;
+ case NE: compare_code = EQ; branch_code = EQ; break;
+ case LT: compare_code = LT; branch_code = NE; break;
+ case LE: compare_code = LT; branch_code = EQ; swap_p = 1; break;
+ case GT: compare_code = LT; branch_code = NE; swap_p = 1; break;
+ case GE: compare_code = LT; branch_code = EQ; break;
+ case LTU: compare_code = LTU; branch_code = NE; break;
+ case LEU: compare_code = LTU; branch_code = EQ; swap_p = 1; break;
+ case GTU: compare_code = LTU; branch_code = NE; swap_p = 1; break;
+ case GEU: compare_code = LTU; branch_code = EQ; break;
+ }
+
+ if (! TARGET_OLD_COMPARE)
+ {
+ /* reg/reg equal comparison */
+ if (compare_code == EQ
+ && register_operand (y, SImode))
+ return gen_rtx (code, mode, x, y);
+ /* reg/zero signed comparison */
+ if ((compare_code == EQ || compare_code == LT)
+ && y == const0_rtx)
+ return gen_rtx (code, mode, x, y);
+ /* reg/smallconst equal comparison */
+ if (compare_code == EQ
+ && GET_CODE (y) == CONST_INT
+ && CMP_INT16_P (INTVAL (y)))
+ {
+ rtx tmp = gen_reg_rtx (SImode);
+ emit_insn (gen_cmp_ne_small_const_insn (tmp, x, y));
+ return gen_rtx (code, mode, tmp, const0_rtx);
+ }
+ /* reg/const equal comparison */
+ if (compare_code == EQ
+ && CONSTANT_P (y))
+ {
+ rtx tmp = force_reg (GET_MODE (x), y);
+ return gen_rtx (code, mode, x, tmp);
+ }
+ }
+
+ if (swap_p && CONSTANT_P (y))
+ y = force_reg (GET_MODE (x), y);
+ else if (CONSTANT_P (y))
+ {
+ int ok_const_p =
+ (code == LTU || code == LEU || code == GTU || code == GEU)
+ ? uint16_operand (y, GET_MODE (y))
+ : reg_or_cmp_int16_operand (y, GET_MODE (y));
+ if (! ok_const_p)
+ y = force_reg (GET_MODE (x), y);
+ }
+
+ switch (compare_code)
+ {
+ case EQ :
+ emit_insn (gen_cmp_eqsi_insn (swap_p ? y : x, swap_p ? x : y));
+ break;
+ case LT :
+ emit_insn (gen_cmp_ltsi_insn (swap_p ? y : x, swap_p ? x : y));
+ break;
+ case LTU :
+ emit_insn (gen_cmp_ltusi_insn (swap_p ? y : x, swap_p ? x : y));
+ break;
+ }
+
+ return gen_rtx (branch_code, VOIDmode, cc_reg, CONST0_RTX (mode));
+}
+
+/* Implements the FUNCTION_ARG_PARTIAL_NREGS macro. */
+
+int
+function_arg_partial_nregs (cum, mode, type, named)
+ CUMULATIVE_ARGS *cum;
+ enum machine_mode mode;
+ tree type;
+ int named;
+{
+ int ret;
+ int size = (((mode == BLKmode && type)
+ ? int_size_in_bytes (type)
+ : GET_MODE_SIZE (mode)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+
+ if (*cum >= M32R_MAX_PARM_REGS)
+ ret = 0;
+ else if (*cum + size > M32R_MAX_PARM_REGS)
+ ret = (*cum + size) - M32R_MAX_PARM_REGS;
+ else
+ ret = 0;
+
+ return ret;
+}
+
+/* Do any needed setup for a variadic function. For the M32R, we must
+ create a register parameter block, and then copy any anonymous arguments
+ in registers to memory.
+
+ CUM has not been updated for the last named argument which has type TYPE
+ and mode MODE, and we rely on this fact. */
+
+void
+m32r_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
+ CUMULATIVE_ARGS *cum;
+ enum machine_mode mode;
+ tree type;
+ int *pretend_size;
+ int no_rtl;
+{
+ int first_anon_arg;
+
+ if (no_rtl)
+ return;
+
+ /* All BLKmode values are passed by reference. */
+ if (mode == BLKmode)
+ abort ();
+
+ /* We must treat `__builtin_va_alist' as an anonymous arg. */
+ if (current_function_varargs)
+ first_anon_arg = *cum;
+ else
+ first_anon_arg = (ROUND_ADVANCE_CUM (*cum, mode, type)
+ + ROUND_ADVANCE_ARG (mode, type));
+
+ if (first_anon_arg < M32R_MAX_PARM_REGS)
+ {
+ /* Note that first_reg_offset < M32R_MAX_PARM_REGS. */
+ int first_reg_offset = first_anon_arg;
+ /* Size in words to "pretend" allocate. */
+ int size = M32R_MAX_PARM_REGS - first_reg_offset;
+ rtx regblock;
+
+ regblock = gen_rtx (MEM, BLKmode,
+ plus_constant (arg_pointer_rtx,
+ FIRST_PARM_OFFSET (0)));
+ move_block_from_reg (first_reg_offset, regblock,
+ size, size * UNITS_PER_WORD);
+
+ *pretend_size = (size * UNITS_PER_WORD);
+ }
+}
+
+/* Cost functions. */
+
+/* Provide the costs of an addressing mode that contains ADDR.
+ If ADDR is not a valid address, its cost is irrelevant.
+
+ This function is trivial at the moment. This code doesn't live
+ in m32r.h so it's easy to experiment. */
+
+int
+m32r_address_cost (addr)
+ rtx addr;
+{
+ return 1;
+}
+
+/* Type of function DECL.
+
+ The result is cached. To reset the cache at the end of a function,
+ call with DECL = NULL_TREE. */
+
+enum m32r_function_type
+m32r_compute_function_type (decl)
+ tree decl;
+{
+ /* Cached value. */
+ static enum m32r_function_type fn_type = M32R_FUNCTION_UNKNOWN;
+ /* Last function we were called for. */
+ static tree last_fn = NULL_TREE;
+
+ /* Resetting the cached value? */
+ if (decl == NULL_TREE)
+ {
+ fn_type = M32R_FUNCTION_UNKNOWN;
+ last_fn = NULL_TREE;
+ return fn_type;
+ }
+
+ if (decl == last_fn && fn_type != M32R_FUNCTION_UNKNOWN)
+ return fn_type;
+
+ /* Compute function type. */
+ fn_type = (lookup_attribute ("interrupt", DECL_MACHINE_ATTRIBUTES (current_function_decl)) != NULL_TREE
+ ? M32R_FUNCTION_INTERRUPT
+ : M32R_FUNCTION_NORMAL);
+
+ last_fn = decl;
+ return fn_type;
+}
+ /* Function prologue/epilogue handlers. */
+
+/* M32R stack frames look like:
+
+ Before call After call
+ +-----------------------+ +-----------------------+
+ | | | |
+ high | local variables, | | local variables, |
+ mem | reg save area, etc. | | reg save area, etc. |
+ | | | |
+ +-----------------------+ +-----------------------+
+ | | | |
+ | arguments on stack. | | arguments on stack. |
+ | | | |
+ SP+0->+-----------------------+ +-----------------------+
+ | reg parm save area, |
+ | only created for |
+ | variable argument |
+ | functions |
+ +-----------------------+
+ | previous frame ptr |
+ +-----------------------+
+ | |
+ | register save area |
+ | |
+ +-----------------------+
+ | return address |
+ +-----------------------+
+ | |
+ | local variables |
+ | |
+ +-----------------------+
+ | |
+ | alloca allocations |
+ | |
+ +-----------------------+
+ | |
+ low | arguments on stack |
+ memory | |
+ SP+0->+-----------------------+
+
+Notes:
+1) The "reg parm save area" does not exist for non variable argument fns.
+2) The "reg parm save area" can be eliminated completely if we saved regs
+ containing anonymous args separately but that complicates things too
+ much (so it's not done).
+3) The return address is saved after the register save area so as to have as
+ many insns as possible between the restoration of `lr' and the `jmp lr'.
+*/
+
+/* Structure to be filled in by m32r_compute_frame_size with register
+ save masks, and offsets for the current function. */
+struct m32r_frame_info
+{
+ unsigned int total_size; /* # bytes that the entire frame takes up */
+ unsigned int extra_size; /* # bytes of extra stuff */
+ unsigned int pretend_size; /* # bytes we push and pretend caller did */
+ unsigned int args_size; /* # bytes that outgoing arguments take up */
+ unsigned int reg_size; /* # bytes needed to store regs */
+ unsigned int var_size; /* # bytes that variables take up */
+ unsigned int gmask; /* mask of saved gp registers */
+ unsigned int save_fp; /* nonzero if fp must be saved */
+ unsigned int save_lr; /* nonzero if lr (return addr) must be saved */
+ int initialized; /* nonzero if frame size already calculated */
+};
+
+/* Current frame information calculated by m32r_compute_frame_size. */
+static struct m32r_frame_info current_frame_info;
+
+/* Zero structure to initialize current_frame_info. */
+static struct m32r_frame_info zero_frame_info;
+
+#define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
+#define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
+
+/* Tell prologue and epilogue if register REGNO should be saved / restored.
+ The return address and frame pointer are treated separately.
+ Don't consider them here. */
+#define MUST_SAVE_REGISTER(regno, interrupt_p) \
+((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \
+ && (regs_ever_live[regno] && (!call_used_regs[regno] || interrupt_p)))
+
+#define MUST_SAVE_FRAME_POINTER (regs_ever_live[FRAME_POINTER_REGNUM])
+#define MUST_SAVE_RETURN_ADDR (regs_ever_live[RETURN_ADDR_REGNUM])
+
+/* Return the bytes needed to compute the frame pointer from the current
+ stack pointer.
+
+ SIZE is the size needed for local variables. */
+
+unsigned int
+m32r_compute_frame_size (size)
+ int size; /* # of var. bytes allocated. */
+{
+ int regno;
+ unsigned int total_size, var_size, args_size, pretend_size, extra_size;
+ unsigned int reg_size;
+ unsigned int gmask;
+ enum m32r_function_type fn_type;
+ int interrupt_p;
+
+ var_size = M32R_STACK_ALIGN (size);
+ args_size = M32R_STACK_ALIGN (current_function_outgoing_args_size);
+ pretend_size = current_function_pretend_args_size;
+ extra_size = FIRST_PARM_OFFSET (0);
+ total_size = extra_size + pretend_size + args_size + var_size;
+ reg_size = 0;
+ gmask = 0;
+
+ /* See if this is an interrupt handler. Call used registers must be saved
+ for them too. */
+ fn_type = m32r_compute_function_type (current_function_decl);
+ interrupt_p = M32R_INTERRUPT_P (fn_type);
+
+ /* Calculate space needed for registers. */
+
+ for (regno = 0; regno < M32R_MAX_INT_REGS; regno++)
+ {
+ if (MUST_SAVE_REGISTER (regno, interrupt_p))
+ {
+ reg_size += UNITS_PER_WORD;
+ gmask |= 1 << regno;
+ }
+ }
+
+ current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER;
+ current_frame_info.save_lr = MUST_SAVE_RETURN_ADDR;
+
+ reg_size += ((current_frame_info.save_fp + current_frame_info.save_lr)
+ * UNITS_PER_WORD);
+ total_size += reg_size;
+
+ /* ??? Not sure this is necessary, and I don't think the epilogue
+ handler will do the right thing if this changes total_size. */
+ total_size = M32R_STACK_ALIGN (total_size);
+
+ /* Save computed information. */
+ current_frame_info.total_size = total_size;
+ current_frame_info.extra_size = extra_size;
+ current_frame_info.pretend_size = pretend_size;
+ current_frame_info.var_size = var_size;
+ current_frame_info.args_size = args_size;
+ current_frame_info.reg_size = reg_size;
+ current_frame_info.gmask = gmask;
+ current_frame_info.initialized = reload_completed;
+
+ /* Ok, we're done. */
+ return total_size;
+}
+
+/* Set up the stack and frame pointer (if desired) for the function. */
+
+void
+m32r_output_function_prologue (file, size)
+ FILE *file;
+ int size;
+{
+ int regno;
+ int total_size, frame_size;
+ char *sp_str = reg_names[STACK_POINTER_REGNUM];
+ char *fp_str = reg_names[FRAME_POINTER_REGNUM];
+ unsigned int gmask = current_frame_info.gmask;
+ enum m32r_function_type fn_type = m32r_compute_function_type (current_function_decl);
+
+ /* If this is an interrupt handler, mark it as such. */
+ if (M32R_INTERRUPT_P (fn_type))
+ {
+ fprintf (file, "\t%s interrupt handler\n",
+ ASM_COMMENT_START);
+ }
+
+ /* This is only for the human reader. */
+ fprintf (file, "\t%s BEGIN PROLOGUE %s vars= %d, regs= %d, args= %d, extra= %d\n",
+ ASM_COMMENT_START, ASM_COMMENT_START,
+ current_frame_info.var_size,
+ current_frame_info.reg_size / 4,
+ current_frame_info.args_size,
+ current_frame_info.extra_size);
+
+ total_size = (! current_frame_info.initialized
+ ? m32r_compute_frame_size (size)
+ : current_frame_info.total_size);
+
+ /* These cases shouldn't happen. Catch them now. */
+ if (total_size == 0 && gmask)
+ abort ();
+
+#if 1
+ /* Allocate space for register arguments if this is a variadic function. */
+ if (current_frame_info.pretend_size != 0)
+ fprintf (file, "\taddi %s,%s%d\n",
+ sp_str, IMMEDIATE_PREFIX,
+ -current_frame_info.pretend_size);
+#else
+ /* If there are unnamed args in registers, save them. */
+ if (current_function_stdarg || current_function_varargs)
+ {
+ int i;
+ fprintf (file, "\taddi %s,%s%d\n",
+ sp_str, IMMEDIATE_PREFIX,
+ - M32R_MAX_PARM_REGS * UNITS_PER_WORD);
+ for (i = 0; i < M32R_MAX_PARM_REGS; ++i)
+ fprintf (file, "\tst %s,@(sp,%d)\n",
+ reg_names[i], i * UNITS_PER_WORD);
+ }
+#endif
+
+ /* Save any registers we need to and set up fp. */
+
+ if (current_frame_info.save_fp)
+ fprintf (file, "\tpush %s\n", fp_str);
+
+ gmask &= ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK);
+
+ /* Save any needed call-saved regs (and call-used if this is an
+ interrupt handler). */
+ for (regno = 0; regno <= M32R_MAX_INT_REGS; ++regno)
+ {
+ if ((gmask & (1 << regno)) != 0)
+ fprintf (file, "\tpush %s\n", reg_names[regno]);
+ }
+
+ if (current_frame_info.save_lr)
+ fprintf (file, "\tpush %s\n", reg_names[RETURN_ADDR_REGNUM]);
+
+ /* Allocate the stack frame. */
+ frame_size = total_size - (current_frame_info.pretend_size
+ + current_frame_info.reg_size);
+ if (frame_size == 0)
+ ; /* nothing to do */
+ else if (frame_size <= 128)
+ fprintf (file, "\taddi %s,%s%d\n",
+ sp_str, IMMEDIATE_PREFIX, -frame_size);
+ else if (frame_size <= 32768)
+ fprintf (file, "\tadd3 %s,%s,%s%d\n",
+ sp_str, sp_str, IMMEDIATE_PREFIX, -frame_size);
+ else
+ fprintf (file, "\tld24 %s,%s%d\n\tsub %s,%s\n",
+ reg_names[PROLOGUE_TMP_REGNUM],
+ IMMEDIATE_PREFIX, frame_size,
+ sp_str, reg_names[PROLOGUE_TMP_REGNUM]);
+
+ if (frame_pointer_needed)
+ fprintf (file, "\tmv %s,%s\n", fp_str, sp_str);
+
+ fprintf (file, "\t%s END PROLOGUE\n", ASM_COMMENT_START);
+}
+
+/* Do any necessary cleanup after a function to restore stack, frame,
+ and regs. */
+
+void
+m32r_output_function_epilogue (file, size)
+ FILE *file;
+ int size;
+{
+ int regno;
+ int noepilogue = FALSE;
+ int total_size;
+ enum m32r_function_type fn_type = m32r_compute_function_type (current_function_decl);
+
+ /* This is only for the human reader. */
+ fprintf (file, "\t%s EPILOGUE\n", ASM_COMMENT_START);
+
+ if (!current_frame_info.initialized)
+ abort ();
+ total_size = current_frame_info.total_size;
+
+ if (total_size == 0)
+ {
+ rtx insn = get_last_insn ();
+
+ /* If the last insn was a BARRIER, we don't have to write any code
+ because a jump (aka return) was put there. */
+ if (GET_CODE (insn) == NOTE)
+ insn = prev_nonnote_insn (insn);
+ if (insn && GET_CODE (insn) == BARRIER)
+ noepilogue = TRUE;
+ }
+
+ if (!noepilogue)
+ {
+ unsigned int pretend_size = current_frame_info.pretend_size;
+ unsigned int frame_size = total_size - pretend_size;
+ unsigned int var_size = current_frame_info.var_size;
+ unsigned int args_size = current_frame_info.args_size;
+ unsigned int gmask = current_frame_info.gmask;
+ int can_trust_sp_p = !current_function_calls_alloca;
+ char *sp_str = reg_names[STACK_POINTER_REGNUM];
+ char *fp_str = reg_names[FRAME_POINTER_REGNUM];
+
+ /* The first thing to do is point the sp at the bottom of the register
+ save area. */
+ if (can_trust_sp_p)
+ {
+ unsigned int reg_offset = var_size + args_size;
+ if (reg_offset == 0)
+ ; /* nothing to do */
+ else if (reg_offset < 128)
+ fprintf (file, "\taddi %s,%s%d\n",
+ sp_str, IMMEDIATE_PREFIX, reg_offset);
+ else if (reg_offset < 32768)
+ fprintf (file, "\tadd3 %s,%s,%s%d\n",
+ sp_str, sp_str, IMMEDIATE_PREFIX, reg_offset);
+ else
+ fprintf (file, "\tld24 %s,%s%d\n\tadd %s,%s\n",
+ reg_names[PROLOGUE_TMP_REGNUM],
+ IMMEDIATE_PREFIX, reg_offset,
+ sp_str, reg_names[PROLOGUE_TMP_REGNUM]);
+ }
+ else if (frame_pointer_needed)
+ {
+ unsigned int reg_offset = var_size + args_size;
+ if (reg_offset == 0)
+ fprintf (file, "\tmv %s,%s\n", sp_str, fp_str);
+ else if (reg_offset < 32768)
+ fprintf (file, "\tadd3 %s,%s,%s%d\n",
+ sp_str, fp_str, IMMEDIATE_PREFIX, reg_offset);
+ else
+ fprintf (file, "\tld24 %s,%s%d\n\tadd %s,%s\n",
+ reg_names[PROLOGUE_TMP_REGNUM],
+ IMMEDIATE_PREFIX, reg_offset,
+ sp_str, reg_names[PROLOGUE_TMP_REGNUM]);
+ }
+ else
+ abort ();
+
+ if (current_frame_info.save_lr)
+ fprintf (file, "\tpop %s\n", reg_names[RETURN_ADDR_REGNUM]);
+
+ /* Restore any saved registers, in reverse order of course. */
+ gmask &= ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK);
+ for (regno = M32R_MAX_INT_REGS - 1; regno >= 0; --regno)
+ {
+ if ((gmask & (1L << regno)) != 0)
+ fprintf (file, "\tpop %s\n", reg_names[regno]);
+ }
+
+ if (current_frame_info.save_fp)
+ fprintf (file, "\tpop %s\n", fp_str);
+
+ /* Remove varargs area if present. */
+ if (current_frame_info.pretend_size != 0)
+ fprintf (file, "\taddi %s,%s%d\n",
+ sp_str, IMMEDIATE_PREFIX, current_frame_info.pretend_size);
+
+ /* Emit the return instruction. */
+ if (M32R_INTERRUPT_P (fn_type))
+ fprintf (file, "\trte\n");
+ else
+ fprintf (file, "\tjmp %s\n", reg_names[RETURN_ADDR_REGNUM]);
+ }
+
+#if 0 /* no longer needed */
+ /* Ensure the function cleanly ends on a 32 bit boundary. */
+ fprintf (file, "\t.fillinsn\n");
+#endif
+
+ /* Reset state info for each function. */
+ current_frame_info = zero_frame_info;
+ m32r_compute_function_type (NULL_TREE);
+}
+
+/* PIC */
+
+/* Emit special PIC prologues and epilogues. */
+
+void
+m32r_finalize_pic ()
+{
+ /* nothing to do */
+}
+
+/* Nested function support. */
+
+/* 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. */
+
+void
+m32r_initialize_trampoline (tramp, fnaddr, cxt)
+ rtx tramp, fnaddr, cxt;
+{
+}
+
+/* Set the cpu type and print out other fancy things,
+ at the top of the file. */
+
+void
+m32r_asm_file_start (file)
+ FILE *file;
+{
+ if (flag_verbose_asm)
+ fprintf (file, "%s M32R/D special options: -G %d\n",
+ ASM_COMMENT_START, g_switch_value);
+}
+
+/* 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.
+ For `%' followed by punctuation, CODE is the punctuation and X is null. */
+
+void
+m32r_print_operand (file, x, code)
+ FILE *file;
+ rtx x;
+ int code;
+{
+ switch (code)
+ {
+ case 'R' :
+ /* Write second word of DImode or DFmode reference,
+ register or memory. */
+ if (GET_CODE (x) == REG)
+ fputs (reg_names[REGNO (x)+1], file);
+ else if (GET_CODE (x) == MEM)
+ {
+ fprintf (file, "@(");
+ /* Handle possible auto-increment. Since it is pre-increment and
+ we have already done it, we can just use an offset of four. */
+ /* ??? This is taken from rs6000.c I think. I don't think it is
+ currently necessary, but keep it around. */
+ if (GET_CODE (XEXP (x, 0)) == PRE_INC
+ || GET_CODE (XEXP (x, 0)) == PRE_DEC)
+ output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
+ else
+ output_address (plus_constant (XEXP (x, 0), 4));
+ fputc (')', file);
+ }
+ else
+ output_operand_lossage ("invalid operand to %R code");
+ return;
+
+ case 'H' : /* High word */
+ case 'L' : /* Low word */
+ if (GET_CODE (x) == REG)
+ {
+ /* L = least significant word, H = most significant word */
+ if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
+ fputs (reg_names[REGNO (x)], file);
+ else
+ fputs (reg_names[REGNO (x)+1], file);
+ }
+ else if (GET_CODE (x) == CONST_INT
+ || GET_CODE (x) == CONST_DOUBLE)
+ {
+ rtx first, second;
+
+ split_double (x, &first, &second);
+ fprintf (file, "0x%08lx",
+ code == 'L' ? INTVAL (first) : INTVAL (second));
+ }
+ else
+ output_operand_lossage ("invalid operand to %H/%L code");
+ return;
+
+ case 'A' :
+ {
+ REAL_VALUE_TYPE d;
+ char str[30];
+
+ if (GET_CODE (x) != CONST_DOUBLE
+ || GET_MODE_CLASS (GET_MODE (x)) != MODE_FLOAT)
+ abort ();
+ REAL_VALUE_FROM_CONST_DOUBLE (d, x);
+ REAL_VALUE_TO_DECIMAL (d, "%.20e", str);
+ fprintf (file, "%s", str);
+ return;
+ }
+
+ case 'B' : /* Bottom half */
+ case 'T' : /* Top half */
+ /* Output the argument to a `seth' insn (sets the Top half-word).
+ For constants output arguments to a seth/or3 pair to set Top and
+ Bottom halves. For symbols output arguments to a seth/add3 pair to
+ set Top and Bottom halves. The difference exists because for
+ constants seth/or3 is more readable but for symbols we need to use
+ the same scheme as `ld' and `st' insns (16 bit addend is signed). */
+ switch (GET_CODE (x))
+ {
+ case CONST_INT :
+ case CONST_DOUBLE :
+ {
+ rtx first, second;
+
+ split_double (x, &first, &second);
+ x = WORDS_BIG_ENDIAN ? second : first;
+ fprintf (file,
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+ "0x%x",
+#else
+ "0x%lx",
+#endif
+ (code == 'B'
+ ? INTVAL (x) & 0xffff
+ : (INTVAL (x) >> 16) & 0xffff));
+ }
+ return;
+ case CONST :
+ case SYMBOL_REF :
+ if (code == 'B'
+ && small_data_operand (x, VOIDmode))
+ {
+ fputs ("sda(", file);
+ output_addr_const (file, x);
+ fputc (')', file);
+ return;
+ }
+ /* fall through */
+ case LABEL_REF :
+ fputs (code == 'T' ? "shigh(" : "low(", file);
+ output_addr_const (file, x);
+ fputc (')', file);
+ return;
+ default :
+ output_operand_lossage ("invalid operand to %T/%B code");
+ return;
+ }
+ break;
+
+ case 'U' :
+ /* ??? wip */
+ /* Output a load/store with update indicator if appropriate. */
+ if (GET_CODE (x) == MEM)
+ {
+ if (GET_CODE (XEXP (x, 0)) == PRE_INC
+ || GET_CODE (XEXP (x, 0)) == PRE_DEC)
+ fputs (".a", file);
+ }
+ else
+ output_operand_lossage ("invalid operand to %U code");
+ return;
+
+ case 'N' :
+ /* Print a constant value negated. */
+ if (GET_CODE (x) == CONST_INT)
+ output_addr_const (file, GEN_INT (- INTVAL (x)));
+ else
+ output_operand_lossage ("invalid operand to %N code");
+ return;
+
+ case 'X' :
+ /* Print a const_int in hex. Used in comments. */
+ if (GET_CODE (x) == CONST_INT)
+ fprintf (file,
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+ "0x%x",
+#else
+ "0x%lx",
+#endif
+ INTVAL (x));
+ return;
+
+ case '#' :
+ fputs (IMMEDIATE_PREFIX, file);
+ return;
+
+#if 0 /* ??? no longer used */
+ case '@' :
+ fputs (reg_names[SDA_REGNUM], file);
+ return;
+#endif
+
+ case 0 :
+ /* Do nothing special. */
+ break;
+
+ default :
+ /* Unknown flag. */
+ output_operand_lossage ("invalid operand output code");
+ }
+
+ switch (GET_CODE (x))
+ {
+ case REG :
+ fputs (reg_names[REGNO (x)], file);
+ break;
+
+ case MEM :
+ fprintf (file, "@(");
+ if (GET_CODE (XEXP (x, 0)) == PRE_INC)
+ output_address (plus_constant (XEXP (XEXP (x, 0), 0),
+ GET_MODE_SIZE (GET_MODE (x))));
+ else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
+ output_address (plus_constant (XEXP (XEXP (x, 0), 0),
+ - GET_MODE_SIZE (GET_MODE (x))));
+ else
+ output_address (XEXP (x, 0));
+ fputc (')', file);
+ break;
+
+ case CONST_DOUBLE :
+ /* We handle SFmode constants here as output_addr_const doesn't. */
+ if (GET_MODE (x) == SFmode)
+ {
+ REAL_VALUE_TYPE d;
+ long l;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (d, x);
+ REAL_VALUE_TO_TARGET_SINGLE (d, l);
+ fprintf (file, "0x%08lx", l);
+ break;
+ }
+
+ /* Fall through. Let output_addr_const deal with it. */
+
+ default :
+ output_addr_const (file, x);
+ break;
+ }
+}
+
+/* Print a memory address as an operand to reference that memory location. */
+
+void
+m32r_print_operand_address (file, addr)
+ FILE *file;
+ rtx addr;
+{
+ register rtx base, index = 0;
+ int offset = 0;
+
+ switch (GET_CODE (addr))
+ {
+ case REG :
+ fputs (reg_names[REGNO (addr)], file);
+ break;
+
+ case PLUS :
+ if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
+ offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);
+ else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);
+ else
+ base = XEXP (addr, 0), index = XEXP (addr, 1);
+ if (GET_CODE (base) == REG)
+ {
+ /* Print the offset first (if present) to conform to the manual. */
+ if (index == 0)
+ {
+ if (offset != 0)
+ fprintf (file, "%d,", offset);
+ fputs (reg_names[REGNO (base)], file);
+ }
+ /* The chip doesn't support this, but left in for generality. */
+ else if (GET_CODE (index) == REG)
+ fprintf (file, "%s,%s",
+ reg_names[REGNO (base)], reg_names[REGNO (index)]);
+ /* Not sure this can happen, but leave in for now. */
+ else if (GET_CODE (index) == SYMBOL_REF)
+ {
+ output_addr_const (file, index);
+ fputc (',', file);
+ fputs (reg_names[REGNO (base)], file);
+ }
+ else
+ abort ();
+ }
+ else if (GET_CODE (base) == LO_SUM)
+ {
+ if (index != 0
+ || GET_CODE (XEXP (base, 0)) != REG)
+ abort ();
+ if (small_data_operand (XEXP (base, 1), VOIDmode))
+ fputs ("sda(", file);
+ else
+ fputs ("low(", file);
+ output_addr_const (file, plus_constant (XEXP (base, 1), offset));
+ fputs ("),", file);
+ fputs (reg_names[REGNO (XEXP (base, 0))], file);
+ }
+ else
+ abort ();
+ break;
+
+ case LO_SUM :
+ if (GET_CODE (XEXP (addr, 0)) != REG)
+ abort ();
+ if (small_data_operand (XEXP (addr, 1), VOIDmode))
+ fputs ("sda(", file);
+ else
+ fputs ("low(", file);
+ output_addr_const (file, XEXP (addr, 1));
+ fputs ("),", file);
+ fputs (reg_names[REGNO (XEXP (addr, 0))], file);
+ break;
+
+ case PRE_INC :
+ case PRE_DEC :
+ /* We shouldn't get here as we've lost the mode of the memory object
+ (which says how much to inc/dec by). */
+ abort ();
+ break;
+
+ default :
+ output_addr_const (file, addr);
+ break;
+ }
+}
diff --git a/gnu/usr.bin/gcc/config/m32r/m32r.h b/gnu/usr.bin/gcc/config/m32r/m32r.h
new file mode 100644
index 00000000000..99ab9c2281c
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m32r/m32r.h
@@ -0,0 +1,1867 @@
+/* Definitions of target machine for GNU compiler, Mitsubishi M32R cpu.
+ Copyright (C) 1996, 1997 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. */
+
+/* Things to do:
+- longlong.h?
+*/
+
+/* ??? Create elf.h and have svr4.h include it. */
+#include "svr4.h"
+
+#undef SWITCH_TAKES_ARG
+#undef WORD_SWITCH_TAKES_ARG
+#undef HANDLE_SYSV_PRAGMA
+#undef SIZE_TYPE
+#undef PTRDIFF_TYPE
+#undef WCHAR_TYPE
+#undef WCHAR_TYPE_SIZE
+#undef ASM_FILE_START
+#undef ASM_OUTPUT_EXTERNAL_LIBCALL
+
+/* Print subsidiary information on the compiler version in use. */
+#define TARGET_VERSION fprintf (stderr, " (m32r)")
+
+/* Switch Recognition by gcc.c. Add -G xx support */
+
+#undef SWITCH_TAKES_ARG
+#define SWITCH_TAKES_ARG(CHAR) \
+(DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
+
+/* Names to predefine in the preprocessor for this target machine. */
+/* __M32R__ is defined by the existing compiler so we use that. */
+#define CPP_PREDEFINES "-Acpu(m32r) -Amachine(m32r) -D__M32R__"
+
+/* Additional flags for the preprocessor. */
+#define CPP_SPEC ""
+
+#define CC1_SPEC "%{G*}"
+
+#undef ASM_SPEC
+#if 0 /* not supported yet */
+#define ASM_SPEC "%{v} %{mrelax:-relax}"
+#else
+#define ASM_SPEC "%{v}"
+#endif
+
+#undef ASM_FINAL_SPEC
+
+#undef LINK_SPEC
+#if 0 /* not supported yet */
+#define LINK_SPEC "%{v} %{mrelax:-relax}"
+#else
+#define LINK_SPEC "%{v}"
+#endif
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "%{!shared:crt0.o%s crtsysc.o%s} crtinit.o%s"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtfini.o%s"
+
+#undef LIB_SPEC
+
+/* Run-time compilation parameters selecting different hardware subsets. */
+
+extern int target_flags;
+
+/* If non-zero, tell the linker to do relaxing.
+ We don't do anything with the option, other than recognize it.
+ LINK_SPEC handles passing -relax to the linker.
+ This can cause incorrect debugging information as line numbers may
+ turn out wrong. This shouldn't be specified unless accompanied with -O2
+ [where the user expects debugging information to be less accurate]. */
+#define TARGET_RELAX_MASK 1
+
+/* For miscellaneous debugging purposes. */
+#define TARGET_DEBUG_MASK 2
+#define TARGET_DEBUG (target_flags & TARGET_DEBUG_MASK)
+
+/* Align loops to 32 byte boundaries (cache line size). */
+/* ??? This option is experimental and is not documented. */
+#define TARGET_ALIGN_LOOPS_MASK 4
+#define TARGET_ALIGN_LOOPS (target_flags & TARGET_ALIGN_LOOPS_MASK)
+
+/* Use old compare/branch support (kept around for awhile for
+ comparison and backoff purposes). */
+/* ??? This option is experimental and is not documented.
+ Eventually it will be deleted. */
+#define TARGET_OLD_COMPARE_MASK 8
+#define TARGET_OLD_COMPARE (target_flags & TARGET_OLD_COMPARE_MASK)
+
+/* Macro to define tables used to set the flags.
+ This is a list in braces of pairs in braces,
+ each pair being { "NAME", VALUE }
+ where VALUE is the bits to set or minus the bits to clear.
+ An empty string NAME is used to identify the default VALUE. */
+
+#define TARGET_SWITCHES \
+{ \
+/* { "relax", TARGET_RELAX_MASK }, \
+ { "no-relax", -TARGET_RELAX_MASK },*/ \
+ { "debug", TARGET_DEBUG_MASK }, \
+ { "align-loops", TARGET_ALIGN_LOOPS_MASK }, \
+ { "no-align-loops", -TARGET_ALIGN_LOOPS_MASK }, \
+ { "old-compare", TARGET_OLD_COMPARE_MASK }, \
+ { "no-old-compare", -TARGET_OLD_COMPARE_MASK }, \
+ SUBTARGET_SWITCHES \
+ { "", TARGET_DEFAULT } \
+}
+
+#define TARGET_DEFAULT (0)
+
+#define SUBTARGET_SWITCHES
+
+/* 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.
+
+ Here is an example which defines `-mshort-data-NUMBER'. If the
+ given option is `-mshort-data-512', the variable `m88k_short_data'
+ will be set to the string `"512"'.
+
+ extern char *m88k_short_data;
+ #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */
+
+extern char *m32r_model_string;
+extern char *m32r_sdata_string;
+#define TARGET_OPTIONS \
+{ \
+ { "model=", &m32r_model_string }, \
+ { "sdata=", &m32r_sdata_string }, \
+}
+
+/* Code Models
+
+ Code models are used to select between two choices of two separate
+ possibilities (address space size, call insn to use):
+
+ small: addresses use 24 bits, use bl to make calls
+ medium: addresses use 32 bits, use bl to make calls (*1)
+ large: addresses use 32 bits, use seth/add3/jl to make calls (*2)
+
+ The fourth is "addresses use 24 bits, use seth/add3/jl to make calls" but
+ using this one doesn't make much sense.
+
+ (*1) The linker may eventually be able to relax seth/add3 -> ld24.
+ (*2) The linker may eventually be able to relax seth/add3/jl -> bl.
+
+ Internally these are recorded as TARGET_ADDR{24,32} and
+ TARGET_CALL{26,32}.
+
+ The __model__ attribute can be used to select the code model to use when
+ accessing particular objects. */
+
+enum m32r_model { M32R_MODEL_SMALL, M32R_MODEL_MEDIUM, M32R_MODEL_LARGE };
+
+extern enum m32r_model m32r_model;
+#define TARGET_MODEL_SMALL (m32r_model == M32R_MODEL_SMALL)
+#define TARGET_MODEL_MEDIUM (m32r_model == M32R_MODEL_MEDIUM)
+#define TARGET_MODEL_LARGE (m32r_model == M32R_MODEL_LARGE)
+#define TARGET_ADDR24 (m32r_model == M32R_MODEL_SMALL)
+#define TARGET_ADDR32 (! TARGET_ADDR24)
+#define TARGET_CALL26 (! TARGET_CALL32)
+#define TARGET_CALL32 (m32r_model == M32R_MODEL_LARGE)
+
+/* The default is the small model. */
+#define M32R_MODEL_DEFAULT "small"
+
+/* Small Data Area
+
+ The SDA consists of sections .sdata, .sbss, and .scommon.
+ .scommon isn't a real section, symbols in it have their section index
+ set to SHN_M32R_SCOMMON, though support for it exists in the linker script.
+
+ Two switches control the SDA:
+
+ -G NNN - specifies the maximum size of variable to go in the SDA
+
+ -msdata=foo - specifies how such variables are handled
+
+ -msdata=none - small data area is disabled
+
+ -msdata=sdata - small data goes in the SDA, special code isn't
+ generated to use it, and special relocs aren't
+ generated
+
+ -msdata=use - small data goes in the SDA, special code is generated
+ to use the SDA and special relocs are generated
+
+ The SDA is not multilib'd, it isn't necessary.
+ MULTILIB_EXTRA_OPTS is set in tmake_file to -msdata=sdata so multilib'd
+ libraries have small data in .sdata/SHN_M32R_SCOMMON so programs that use
+ -msdata=use will successfully link with them (references in header files
+ will cause the compiler to emit code that refers to library objects in
+ .data). ??? There can be a problem if the user passes a -G value greater
+ than the default and a library object in a header file is that size.
+ The default is 8 so this should be rare - if it occurs the user
+ is required to rebuild the libraries or use a smaller value for -G.
+*/
+
+/* Maximum size of variables that go in .sdata/.sbss.
+ The -msdata=foo switch also controls how small variables are handled. */
+#define SDATA_DEFAULT_SIZE 8
+
+extern int g_switch_value; /* value of the -G xx switch */
+extern int g_switch_set; /* whether -G xx was passed. */
+
+enum m32r_sdata { M32R_SDATA_NONE, M32R_SDATA_SDATA, M32R_SDATA_USE };
+
+extern enum m32r_sdata m32r_sdata;
+#define TARGET_SDATA_NONE (m32r_sdata == M32R_SDATA_NONE)
+#define TARGET_SDATA_SDATA (m32r_sdata == M32R_SDATA_SDATA)
+#define TARGET_SDATA_USE (m32r_sdata == M32R_SDATA_USE)
+
+/* Default is to disable the SDA
+ [for upward compatibility with previous toolchains]. */
+#define M32R_SDATA_DEFAULT "none"
+
+/* Define this macro as a C expression for the initializer of an array of
+ string to tell the driver program which options are defaults for this
+ target and thus do not need to be handled specially when using
+ `MULTILIB_OPTIONS'. */
+#define MULTILIB_DEFAULTS { "mmodel=small" }
+
+/* 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. */
+
+extern void m32r_init ();
+
+#define OVERRIDE_OPTIONS \
+do { \
+ /* These need to be done at start up. It's convenient to do them here. */ \
+ m32r_init (); \
+} while (0)
+
+/* Define this macro if debugging can be performed even without a
+ frame pointer. If this macro is defined, GNU CC will turn on the
+ `-fomit-frame-pointer' option whenever `-O' is specified. */
+#define CAN_DEBUG_WITHOUT_FP
+
+/* Target machine storage layout. */
+
+/* Define to use software floating point emulator for REAL_ARITHMETIC and
+ decimal <-> binary conversion. */
+#define REAL_ARITHMETIC
+
+/* Define this if most significant bit is lowest numbered
+ in instructions that operate on numbered bit-fields. */
+#define BITS_BIG_ENDIAN 1
+
+/* Define this if most significant byte of a word is the lowest numbered. */
+#define BYTES_BIG_ENDIAN 1
+
+/* Define this if most significant word of a multiword number is the lowest
+ numbered. */
+#define WORDS_BIG_ENDIAN 1
+
+/* Define this macro if WORDS_BIG_ENDIAN is not constant. This must
+ be a constant value with the same meaning as WORDS_BIG_ENDIAN,
+ which will be used only when compiling libgcc2.c. Typically the
+ value will be set based on preprocessor defines. */
+/*#define LIBGCC2_WORDS_BIG_ENDIAN 1*/
+
+/* 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 68000, 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
+
+/* 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 macro if the promotion described by `PROMOTE_MODE'
+ should also be done for outgoing function arguments. */
+/*#define PROMOTE_FUNCTION_ARGS*/
+
+/* Likewise, if the function return value is promoted.
+ If defined, FUNCTION_VALUE must perform the same promotions done by
+ PROMOTE_MODE. */
+/*#define PROMOTE_FUNCTION_RETURN*/
+
+/* 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
+
+/* ALIGN FRAMES on word boundaries */
+#define M32R_STACK_ALIGN(LOC) (((LOC)+3) & ~3)
+
+/* Allocation boundary (in *bits*) for the code of a function. */
+#define FUNCTION_BOUNDARY 32
+
+/* Alignment of field after `int : 0' in a structure. */
+#define EMPTY_FIELD_BOUNDARY 32
+
+/* Every structure's size must be a multiple of this. */
+#define STRUCTURE_SIZE_BOUNDARY 8
+
+/* A bitfield declared as `int' forces `int' alignment for the struct. */
+#define PCC_BITFIELD_TYPE_MATTERS 1
+
+/* No data type wants to be aligned rounder than this. */
+#define BIGGEST_ALIGNMENT 32
+
+/* The best alignment to use in cases where we have a choice. */
+#define FASTEST_ALIGNMENT 32
+
+/* Make strings word-aligned so strcpy from constants will be faster. */
+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
+ ((TREE_CODE (EXP) == STRING_CST \
+ && (ALIGN) < FASTEST_ALIGNMENT) \
+ ? FASTEST_ALIGNMENT : (ALIGN))
+
+/* Make arrays of chars word-aligned for the same reasons. */
+#define DATA_ALIGNMENT(TYPE, ALIGN) \
+ (TREE_CODE (TYPE) == ARRAY_TYPE \
+ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
+ && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
+
+/* Set this nonzero if move instructions will actually fail to work
+ when given unaligned data. */
+#define STRICT_ALIGNMENT 1
+
+/* Layout of source language data types. */
+
+#define SHORT_TYPE_SIZE 16
+#define INT_TYPE_SIZE 32
+#define LONG_TYPE_SIZE 32
+#define LONG_LONG_TYPE_SIZE 64
+#define FLOAT_TYPE_SIZE 32
+#define DOUBLE_TYPE_SIZE 64
+#define LONG_DOUBLE_TYPE_SIZE 64
+
+/* Define this as 1 if `char' should by default be signed; else as 0. */
+#define DEFAULT_SIGNED_CHAR 1
+
+#define SIZE_TYPE "long unsigned int"
+#define PTRDIFF_TYPE "long int"
+#define WCHAR_TYPE "short unsigned int"
+#define WCHAR_TYPE_SIZE 16
+
+/* 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
+
+/* Standard register usage. */
+
+/* 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. */
+#define FIRST_PSEUDO_REGISTER 18
+
+/* 1 for registers that have pervasive standard uses
+ and are not available for the register allocator.
+
+ 0-3 - arguments/results
+ 4-5 - call used [4 is used as a tmp during prologue/epilogue generation]
+ 6 - call used, gptmp
+ 7 - call used, static chain pointer
+ 8-11 - call saved
+ 12 - call saved [reserved for global pointer]
+ 13 - frame pointer
+ 14 - subroutine link register
+ 15 - stack pointer
+ 16 - arg pointer
+ 17 - carry flag
+
+ By default, the extension registers are not available. */
+
+#define FIXED_REGISTERS \
+{ 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 1, \
+ 1, 0 }
+
+/* 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 \
+{ 1, 1, 1, 1, 1, 1, 1, 1, \
+ 0, 0, 0, 0, 0, 0, 1, 1, \
+ 1, 1 }
+
+/* Zero or more C statements that may conditionally modify two variables
+ `fixed_regs' and `call_used_regs' (both of type `char []') after they
+ have been initialized from the two preceding macros.
+
+ This is necessary in case the fixed or call-clobbered registers depend
+ on target flags.
+
+ You need not define this macro if it has no work to do. */
+
+/*#define CONDITIONAL_REGISTER_USAGE*/
+
+/* If defined, an initializer for a vector of integers, containing the
+ numbers of hard registers in the order in which GNU CC should
+ prefer to use them (from most preferred to least). */
+#if 1 /* better for int code */
+#define REG_ALLOC_ORDER \
+{ 4, 5, 6, 7, 2, 3, 8, 9, 10, 11, 12, 13, 14, 0, 1, 15, 16, 17 }
+#else /* better for fp code at expense of int code */
+#define REG_ALLOC_ORDER \
+{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }
+#endif
+
+/* 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. */
+#define HARD_REGNO_NREGS(REGNO, MODE) \
+((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. */
+extern unsigned int m32r_hard_regno_mode_ok[];
+extern unsigned int m32r_mode_class[];
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+((m32r_hard_regno_mode_ok[REGNO] & m32r_mode_class[MODE]) != 0)
+
+/* A C expression that is nonzero if it is desirable to choose
+ register allocation so as to avoid move instructions between a
+ value of mode MODE1 and a value of mode MODE2.
+
+ If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R,
+ MODE2)' are ever different for any R, then `MODES_TIEABLE_P (MODE1,
+ MODE2)' must be zero. */
+
+/* Tie QI/HI/SI modes together. */
+#define MODES_TIEABLE_P(MODE1, MODE2) \
+(GET_MODE_CLASS (MODE1) == MODE_INT \
+ && GET_MODE_CLASS (MODE2) == MODE_INT \
+ && GET_MODE_SIZE (MODE1) <= UNITS_PER_WORD \
+ && GET_MODE_SIZE (MODE2) <= UNITS_PER_WORD)
+
+/* Register classes and constants. */
+
+/* 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 is important that any condition codes have class NO_REGS.
+ See `register_operand'. */
+
+enum reg_class {
+ NO_REGS, CARRY_REG, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
+};
+
+#define N_REG_CLASSES (int) LIM_REG_CLASSES
+
+/* Give names of register classes as strings for dump file. */
+#define REG_CLASS_NAMES \
+{ "NO_REGS", "CARRY_REG", "GENERAL_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}, {0x20000}, {0x1ffff}, {0x3ffff} }
+
+/* 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. */
+extern enum reg_class m32r_regno_reg_class[];
+#define REGNO_REG_CLASS(REGNO) \
+(m32r_regno_reg_class[REGNO])
+
+/* The class value for index registers, and the one for base regs. */
+#define INDEX_REG_CLASS GENERAL_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) NO_REGS
+
+/* 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_BASE_P(REGNO) \
+((REGNO) < FIRST_PSEUDO_REGISTER \
+ ? GPR_P (REGNO) || (REGNO) == ARG_POINTER_REGNUM \
+ : GPR_P (reg_renumber[REGNO]))
+#define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_BASE_P(REGNO)
+
+/* 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. */
+#define PREFERRED_RELOAD_CLASS(X,CLASS) \
+(CLASS)
+
+/* Return the maximum number of consecutive registers
+ needed to represent mode MODE in a register of class CLASS. */
+#define CLASS_MAX_NREGS(CLASS, MODE) \
+((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* The letters I, J, K, L, M, N, O, P 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 used for 8 bit signed immediates.
+ 'J' is used for 16 bit signed immediates.
+ 'K' is used for 16 bit unsigned immediates.
+ 'L' is used for 16 bit immediates left shifted by 16 (sign ???).
+ 'M' is used for 24 bit unsigned immediates.
+ 'N' is used for any 32 bit non-symbolic value.
+ 'O' is used for 5 bit unsigned immediates (shift count).
+ 'P' is used for 16 bit signed immediates for compares
+ (values in the range -32767 to +32768). */
+
+/* local to this file */
+#define INT8_P(X) ((unsigned) ((X) + 0x80) < 0x100)
+#define INT16_P(X) ((unsigned) ((X) + 0x8000) < 0x10000)
+#define CMP_INT16_P(X) ((unsigned) ((X) - 1 + 0x8000) < 0x10000)
+#define UINT16_P(X) ((unsigned) (X) < 0x10000)
+#define UPPER16_P(X) (((X) & ~0xffff0000) == 0)
+#define UINT24_P(X) ((unsigned) (X) < 0x1000000)
+#define INT32_P(X) ((X) >= (-(HOST_WIDE_INT) 0x7fffffff - 1) \
+ && (X) <= (unsigned HOST_WIDE_INT) 0xffffffff)
+#define UINT5_P(X) ((unsigned) (X) < 32)
+
+#define CONST_OK_FOR_LETTER_P(VALUE, C) \
+((C) == 'I' ? INT8_P (VALUE) \
+ : (C) == 'J' ? INT16_P (VALUE) \
+ : (C) == 'K' ? UINT16_P (VALUE) \
+ : (C) == 'L' ? UPPER16_P (VALUE) \
+ : (C) == 'M' ? UINT24_P (VALUE) \
+ : (C) == 'N' ? INT32_P (VALUE) \
+ : (C) == 'O' ? UINT5_P (VALUE) \
+ : (C) == 'P' ? CMP_INT16_P (VALUE) \
+ : 0)
+
+/* Similar, but for floating constants, and defining letters G and H.
+ Here VALUE is the CONST_DOUBLE rtx itself.
+ For the m32r, handle a few constants inline.
+ ??? We needn't treat DI and DF modes differently, but for now we do. */
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
+((C) == 'G' ? easy_di_const (VALUE) \
+ : (C) == 'H' ? easy_df_const (VALUE) \
+ : 0)
+
+/* A C expression that defines the optional machine-dependent constraint
+ letters that can be used to segregate specific types of operands,
+ usually memory references, for the target machine. It should return 1 if
+ VALUE corresponds to the operand type represented by the constraint letter
+ C. If C is not defined as an extra constraint, the value returned should
+ be 0 regardless of VALUE. */
+/* Q is for symbolic addresses loadable with ld24.
+ R is for symbolic addresses when ld24 can't be used. */
+#define EXTRA_CONSTRAINT(VALUE, C) \
+((C) == 'Q' \
+ ? ((TARGET_ADDR24 && GET_CODE (VALUE) == LABEL_REF) \
+ || addr24_operand (VALUE, VOIDmode)) \
+ : (C) == 'R' \
+ ? ((TARGET_ADDR32 && GET_CODE (VALUE) == LABEL_REF) \
+ || addr32_operand (VALUE, VOIDmode)) \
+ : 0)
+
+/* Stack layout and stack pointer usage. */
+
+/* Define this macro if pushing a word onto the stack moves the stack
+ pointer to 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 from the frame pointer. */
+/*#define FRAME_GROWS_DOWNWARD*/
+
+/* Offset from frame pointer 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. */
+/* The frame pointer points at the same place as the stack pointer, except if
+ alloca has been called. */
+#define STARTING_FRAME_OFFSET \
+M32R_STACK_ALIGN (current_function_outgoing_args_size)
+
+/* Offset from the stack pointer register to the first location at which
+ outgoing arguments are placed. */
+#define STACK_POINTER_OFFSET 0
+
+/* Offset of first parameter from the argument pointer register value. */
+#define FIRST_PARM_OFFSET(FNDECL) 0
+
+/* A C expression whose value is RTL representing the address in a
+ stack frame where the pointer to the caller's frame is stored.
+ Assume that FRAMEADDR is an RTL expression for the address of the
+ stack frame itself.
+
+ If you don't define this macro, the default is to return the value
+ of FRAMEADDR--that is, the stack frame address is also the address
+ of the stack word that points to the previous frame. */
+/*define DYNAMIC_CHAIN_ADDRESS (FRAMEADDR)*/
+
+/* A C expression whose value is RTL representing the value of the
+ return address for the frame COUNT steps up from the current frame.
+ FRAMEADDR is the frame pointer of the COUNT frame, or the frame
+ pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME'
+ is defined. */
+/* The current return address is in r14. */
+#if 0 /* The default value should work. */
+#define RETURN_ADDR_RTX(COUNT, FRAME) \
+(((COUNT) == -1) \
+ ? gen_rtx (REG, Pmode, 14) \
+ : copy_to_reg (gen_rtx (MEM, Pmode, \
+ memory_address (Pmode, plus_constant ((FRAME), UNITS_PER_WORD)))))
+#endif
+
+/* Register to use for pushing function arguments. */
+#define STACK_POINTER_REGNUM 15
+
+/* Base register for access to local variables of the function. */
+#define FRAME_POINTER_REGNUM 13
+
+/* Base register for access to arguments of the function. */
+#define ARG_POINTER_REGNUM 16
+
+/* The register number of the return address pointer register, which
+ is used to access the current function's return address from the
+ stack. On some machines, the return address is not at a fixed
+ offset from the frame pointer or stack pointer or argument
+ pointer. This register can be defined to point to the return
+ address on the stack, and then be converted by `ELIMINABLE_REGS'
+ into either the frame pointer or stack pointer.
+
+ Do not define this macro unless there is no other way to get the
+ return address from the stack. */
+/* ??? revisit */
+/* #define RETURN_ADDRESS_POINTER_REGNUM */
+
+/* Register in which static-chain is passed to a function. This must
+ not be a register used by the prologue. */
+#define STATIC_CHAIN_REGNUM 7
+
+/* These aren't official macros. */
+#define PROLOGUE_TMP_REGNUM 4
+#define RETURN_ADDR_REGNUM 14
+/* #define GP_REGNUM 12 */
+#define CARRY_REGNUM 17
+#define M32R_MAX_INT_REGS 16
+
+#define GPR_P(REGNO) ((unsigned) (REGNO) < M32R_MAX_INT_REGS)
+
+/* Eliminating the frame and arg pointers. */
+
+/* A C expression which is nonzero if a function must have and use a
+ frame pointer. This expression is evaluated in the reload pass.
+ If its value is nonzero the function will have a frame pointer. */
+#define FRAME_POINTER_REQUIRED \
+(current_function_calls_alloca)
+
+#if 0
+/* C statement to store the difference between the frame pointer
+ and the stack pointer values immediately after the function prologue.
+ If `ELIMINABLE_REGS' is defined, this macro will be not be used and
+ need not be defined. */
+#define INITIAL_FRAME_POINTER_OFFSET(VAR) \
+((VAR) = m32r_compute_frame_size (get_frame_size ()))
+#endif
+
+/* If defined, this macro specifies a table of register pairs used to
+ eliminate unneeded registers that point into the stack frame. If
+ it is not defined, the only elimination attempted by the compiler
+ is to replace references to the frame pointer with references to
+ the stack pointer.
+
+ Note that the elimination of the argument pointer with the stack
+ pointer is specified first since that is the preferred elimination. */
+
+#define ELIMINABLE_REGS \
+{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
+ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
+ { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }} \
+
+/* A C expression that returns non-zero if the compiler is allowed to
+ try to replace register number FROM-REG with register number
+ TO-REG. This macro need only be defined if `ELIMINABLE_REGS' is
+ defined, and will usually be the constant 1, since most of the
+ cases preventing register elimination are things that the compiler
+ already knows about. */
+
+#define CAN_ELIMINATE(FROM, TO) \
+((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \
+ ? ! frame_pointer_needed \
+ : 1)
+
+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It
+ specifies the initial difference between the specified pair of
+ registers. This macro must be defined if `ELIMINABLE_REGS' is
+ defined. */
+
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+{ \
+ int size = m32r_compute_frame_size (get_frame_size ()); \
+ \
+ if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
+ (OFFSET) = 0; \
+ else if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM) \
+ (OFFSET) = size - current_function_pretend_args_size; \
+ else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
+ (OFFSET) = size - current_function_pretend_args_size; \
+ else \
+ abort (); \
+}
+
+/* Function argument passing. */
+
+/* When a prototype says `char' or `short', really pass an `int'. */
+#define PROMOTE_PROTOTYPES
+
+/* If defined, the maximum amount of space required for outgoing
+ arguments will be computed and placed into the variable
+ `current_function_outgoing_args_size'. No space will be pushed
+ onto the stack for each call; instead, the function prologue should
+ increase the stack frame size by this amount. */
+#define ACCUMULATE_OUTGOING_ARGS
+
+/* Define this macro if functions should assume that stack space has
+ been allocated for arguments even when their values are passed in
+ registers.
+
+ The value of this macro is the size, in bytes, of the area
+ reserved for arguments passed in registers for the function
+ represented by FNDECL.
+
+ This space can be allocated by the caller, or be a part of the
+ machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
+ which. */
+#if 0
+#define REG_PARM_STACK_SPACE(FNDECL) \
+(M32R_MAX_PARM_REGS * UNITS_PER_WORD)
+#endif
+
+/* 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. */
+#define RETURN_POPS_ARGS(DECL, FUNTYPE, SIZE) 0
+
+/* 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. */
+#define CUMULATIVE_ARGS int
+
+/* 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,INDIRECT) \
+((CUM) = 0)
+
+/* The number of registers used for parameter passing. Local to this file. */
+#define M32R_MAX_PARM_REGS 4
+
+/* 1 if N is a possible register number for function argument passing. */
+#define FUNCTION_ARG_REGNO_P(N) \
+((unsigned) (N) < M32R_MAX_PARM_REGS)
+
+/* The ROUND_ADVANCE* macros are local to this file. */
+/* Round SIZE up to a word boundary. */
+#define ROUND_ADVANCE(SIZE) \
+(((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* Round arg MODE/TYPE up to the next word boundary. */
+#define ROUND_ADVANCE_ARG(MODE, TYPE) \
+((MODE) == BLKmode \
+ ? ROUND_ADVANCE (int_size_in_bytes (TYPE)) \
+ : ROUND_ADVANCE (GET_MODE_SIZE (MODE)))
+
+/* Round CUM up to the necessary point for argument MODE/TYPE. */
+#if 0
+#define ROUND_ADVANCE_CUM(CUM, MODE, TYPE) \
+((((MODE) == BLKmode ? TYPE_ALIGN (TYPE) : GET_MODE_BITSIZE (MODE)) \
+ > BITS_PER_WORD) \
+ ? ((CUM) + 1 & ~1) \
+ : (CUM))
+#else
+#define ROUND_ADVANCE_CUM(CUM, MODE, TYPE) (CUM)
+#endif
+
+/* Return boolean indicating arg of type TYPE and mode MODE will be passed in
+ a reg. This includes arguments that have to be passed by reference as the
+ pointer to them is passed in a reg if one is available (and that is what
+ we're given).
+ This macro is only used in this file. */
+#define PASS_IN_REG_P(CUM, MODE, TYPE, NAMED) \
+(ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE)) < M32R_MAX_PARM_REGS)
+
+/* Determine where to put an argument 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). */
+/* On the M32R the first M32R_MAX_PARM_REGS args are normally in registers
+ and the rest are pushed. */
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
+(PASS_IN_REG_P ((CUM), (MODE), (TYPE), (NAMED)) \
+ ? gen_rtx (REG, (MODE), ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE))) \
+ : 0)
+
+/* ??? Quick hack to try to get varargs working the normal way. */
+#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
+(((! current_function_varargs || (NAMED)) \
+ && PASS_IN_REG_P ((CUM), (MODE), (TYPE), (NAMED))) \
+ ? gen_rtx (REG, (MODE), ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE))) \
+ : 0)
+
+/* A C expression for the number of words, at the beginning of an
+ argument, must be put in registers. The value must be zero for
+ arguments that are passed entirely in registers or that are entirely
+ pushed on the stack.
+
+ On some machines, certain arguments must be passed partially in
+ registers and partially in memory. On these machines, typically the
+ first @var{n} words of arguments are passed in registers, and the rest
+ on the stack. If a multi-word argument (a @code{double} or a
+ structure) crosses that boundary, its first few words must be passed
+ in registers and the rest must be pushed. This macro tells the
+ compiler when this occurs, and how many of the words should go in
+ registers. */
+#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
+ function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
+
+/* A C expression that indicates when an argument must be passed by
+ reference. If nonzero for an argument, a copy of that argument is
+ made in memory and a pointer to the argument is passed instead of
+ the argument itself. The pointer is passed in whatever way is
+ appropriate for passing a pointer to that type. */
+/* All arguments greater than 8 bytes are passed this way. */
+#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
+((TYPE) && int_size_in_bytes (TYPE) > 8)
+
+/* 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) \
+((CUM) = (ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE)) \
+ + ROUND_ADVANCE_ARG ((MODE), (TYPE))))
+
+/* If defined, a C expression that gives the alignment boundary, in bits,
+ of an argument with the specified mode and type. If it is not defined,
+ PARM_BOUNDARY is used for all arguments. */
+#if 0
+/* We assume PARM_BOUNDARY == UNITS_PER_WORD here. */
+#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
+(((TYPE) ? TYPE_ALIGN (TYPE) : GET_MODE_BITSIZE (MODE)) <= PARM_BOUNDARY \
+ ? PARM_BOUNDARY \
+ : 2 * PARM_BOUNDARY)
+#endif
+
+#if 0
+/* If defined, is a C expression that produces the machine-specific
+ code for a call to `__builtin_saveregs'. This code will be moved
+ to the very beginning of the function, before any parameter access
+ are made. The return value of this function should be an RTX that
+ contains the value to use as the return of `__builtin_saveregs'.
+
+ The argument ARGS is a `tree_list' containing the arguments that
+ were passed to `__builtin_saveregs'.
+
+ If this macro is not defined, the compiler will output an ordinary
+ call to the library function `__builtin_saveregs'. */
+extern struct rtx *m32r_expand_builtin_savergs ();
+#define EXPAND_BUILTIN_SAVEREGS(ARGS) m32r_expand_builtin_saveregs (ARGS)
+#endif
+
+/* This macro offers an alternative
+ to using `__builtin_saveregs' and defining the macro
+ `EXPAND_BUILTIN_SAVEREGS'. Use it to store the anonymous register
+ arguments into the stack so that all the arguments appear to have
+ been passed consecutively on the stack. Once this is done, you
+ can use the standard implementation of varargs that works for
+ machines that pass all their arguments on the stack.
+
+ The argument ARGS_SO_FAR is the `CUMULATIVE_ARGS' data structure,
+ containing the values that obtain after processing of the named
+ arguments. The arguments MODE and TYPE describe the last named
+ argument--its machine mode and its data type as a tree node.
+
+ The macro implementation should do two things: first, push onto the
+ stack all the argument registers *not* used for the named
+ arguments, and second, store the size of the data thus pushed into
+ the `int'-valued variable whose name is supplied as the argument
+ PRETEND_SIZE. The value that you store here will serve as
+ additional offset for setting up the stack frame.
+
+ If the argument NO_RTL is nonzero, it means that the
+ arguments of the function are being analyzed for the second time.
+ This happens for an inline function, which is not actually
+ compiled until the end of the source file. The macro
+ `SETUP_INCOMING_VARARGS' should not generate any instructions in
+ this case. */
+
+#define SETUP_INCOMING_VARARGS(ARGS_SO_FAR, MODE, TYPE, PRETEND_SIZE, NO_RTL) \
+m32r_setup_incoming_varargs (&ARGS_SO_FAR, MODE, TYPE, &PRETEND_SIZE, NO_RTL)
+
+/* Function results. */
+
+/* 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), 0)
+
+/* 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, 0)
+
+/* 1 if N is a possible register number for a function value
+ as seen by the caller. */
+/* ??? What about r1 in DI/DF values. */
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == 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. */
+#define RETURN_IN_MEMORY(TYPE) \
+(int_size_in_bytes (TYPE) > 8)
+
+/* Tell GCC to use RETURN_IN_MEMORY. */
+#define DEFAULT_PCC_STRUCT_RETURN 0
+
+/* Register in which address to store a structure value
+ is passed to a function, or 0 to use `invisible' first argument. */
+#define STRUCT_VALUE 0
+
+/* Function entry and exit. */
+
+/* Initialize data used by insn expanders. This is called from
+ init_emit, once for each function, before code is generated. */
+#define INIT_EXPANDERS m32r_init_expanders ()
+
+/* 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) \
+m32r_output_function_prologue (FILE, SIZE)
+
+/* 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. */
+#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. */
+#define FUNCTION_EPILOGUE(FILE, SIZE) \
+m32r_output_function_epilogue (FILE, SIZE)
+
+/* Output assembler code to FILE to increment profiler label # LABELNO
+ for profiling a function entry. */
+#define FUNCTION_PROFILER(FILE, LABELNO)
+
+/* Trampolines. */
+
+/* On the M32R, the trampoline is
+
+ ld24 r7,STATIC
+ ld24 r6,FUNCTION
+ jmp r6
+ nop
+
+ ??? Need addr32 support.
+*/
+
+/* Length in bytes 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) \
+do { \
+ emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 0)), \
+ plus_constant ((CXT), 0xe7000000)); \
+ emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 4)), \
+ plus_constant ((FNADDR), 0xe6000000)); \
+ emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 8)), \
+ GEN_INT (0x1fc67000)); \
+ emit_insn (gen_flush_icache (validize_mem (gen_rtx (MEM, SImode, TRAMP)))); \
+} while (0)
+
+/* Library calls. */
+
+/* Generate calls to memcpy, memcmp and memset. */
+#define TARGET_MEM_FUNCTIONS
+
+/* Addressing modes, and classification of registers for them. */
+
+/* Maximum number of registers that can appear in a valid memory address. */
+#define MAX_REGS_PER_ADDRESS 1
+
+/* We have post-inc load and pre-dec,pre-inc store,
+ but only for 4 byte vals. */
+#if 0
+#define HAVE_PRE_DECREMENT
+#define HAVE_PRE_INCREMENT
+#define HAVE_POST_INCREMENT
+#endif
+
+/* Recognize any constant value that is a valid address. */
+#define CONSTANT_ADDRESS_P(X) \
+(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
+ || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST)
+
+/* Nonzero if the constant value X is a legitimate general operand.
+ We don't allow (plus symbol large-constant) as the relocations can't
+ describe it. INTVAL > 32767 handles both 16 bit and 24 bit relocations.
+ We allow all CONST_DOUBLE's as the md file patterns will force the
+ constant to memory if they can't handle them. */
+
+#define LEGITIMATE_CONSTANT_P(X) \
+(! (GET_CODE (X) == CONST \
+ && GET_CODE (XEXP (X, 0)) == PLUS \
+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
+ && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
+ && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (X, 0), 1)) > 32767))
+
+/* 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. */
+
+#ifdef REG_OK_STRICT
+
+/* Nonzero if X is a hard reg that can be used as a base reg. */
+#define REG_OK_FOR_BASE_P(X) GPR_P (REGNO (X))
+/* Nonzero if X is a hard reg that can be used as an index. */
+#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)
+
+#else
+
+/* Nonzero if X is a hard reg that can be used as a base reg
+ or if it is a pseudo reg. */
+#define REG_OK_FOR_BASE_P(X) \
+(GPR_P (REGNO (X)) \
+ || (REGNO (X)) == ARG_POINTER_REGNUM \
+ || REGNO (X) >= FIRST_PSEUDO_REGISTER)
+/* Nonzero if X is a hard reg that can be used as an index
+ or if it is a pseudo reg. */
+#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_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. */
+
+/* local to this file */
+#define RTX_OK_FOR_BASE_P(X) \
+(REG_P (X) && REG_OK_FOR_BASE_P (X))
+
+/* local to this file */
+#define RTX_OK_FOR_OFFSET_P(X) \
+(GET_CODE (X) == CONST_INT && INT16_P (INTVAL (X)))
+
+/* local to this file */
+#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X) \
+(GET_CODE (X) == PLUS \
+ && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \
+ && RTX_OK_FOR_OFFSET_P (XEXP (X, 1)))
+
+/* local to this file */
+#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X) \
+(GET_CODE (X) == LO_SUM \
+ && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \
+ && CONSTANT_P (XEXP (X, 1)))
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+{ if (RTX_OK_FOR_BASE_P (X)) \
+ goto ADDR; \
+ if (LEGITIMATE_OFFSET_ADDRESS_P ((MODE), (X))) \
+ goto ADDR; \
+ if (LEGITIMATE_LO_SUM_ADDRESS_P ((MODE), (X))) \
+ goto ADDR; \
+}
+
+/* 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.
+
+ ??? Is there anything useful we can do here for the M32R? */
+
+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)
+
+/* Go to LABEL if ADDR (a legitimate address expression)
+ has an effect that depends on the machine mode it is used for. */
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
+do { \
+ if (GET_CODE (ADDR) == PRE_DEC) \
+ goto LABEL; \
+ if (GET_CODE (ADDR) == PRE_INC) \
+ goto LABEL; \
+ if (GET_CODE (ADDR) == POST_INC) \
+ goto LABEL; \
+} while (0)
+
+/* Condition code usage. */
+
+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
+ return the mode to be used for the comparison. */
+extern enum machine_mode m32r_select_cc_mode ();
+#define SELECT_CC_MODE(OP, X, Y) \
+m32r_select_cc_mode (OP, X, Y)
+
+/* Return non-zero if SELECT_CC_MODE will never return MODE for a
+ floating point inequality comparison. */
+#define REVERSIBLE_CC_MODE(MODE) 1 /*???*/
+
+/* Costs. */
+
+/* ??? I'm quite sure I don't understand enough of the subtleties involved
+ in choosing the right numbers to use here, but there doesn't seem to be
+ enough documentation on this. What I've done is define an insn to cost
+ 4 "units" and work from there. COSTS_N_INSNS (N) is defined as (N) * 4 - 2
+ so that seems reasonable. Some values are supposed to be defined relative
+ to each other and thus aren't necessarily related to COSTS_N_INSNS. */
+
+/* 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. */
+/* Small integers are as cheap as registers. 4 byte values can be fetched
+ as immediate constants - let's give that the cost of an extra insn. */
+#define CONST_COSTS(X, CODE, OUTER_CODE) \
+ case CONST_INT : \
+ if (INT16_P (INTVAL (X))) \
+ return 0; \
+ /* fall through */ \
+ case CONST : \
+ case LABEL_REF : \
+ case SYMBOL_REF : \
+ return 4; \
+ case CONST_DOUBLE : \
+ { \
+ rtx high, low; \
+ split_double (X, &high, &low); \
+ return 4 * (!INT16_P (INTVAL (high)) \
+ + !INT16_P (INTVAL (low))); \
+ }
+
+/* Compute the cost of an address. */
+#define ADDRESS_COST(ADDR) m32r_address_cost (ADDR)
+
+/* Compute extra cost of moving data between one register class
+ and another. */
+#define REGISTER_MOVE_COST(CLASS1, CLASS2) 2
+
+/* Compute the cost of moving data between registers and memory. */
+/* Memory is 3 times as expensive as registers.
+ ??? Is that the right way to look at it? */
+#define MEMORY_MOVE_COST(MODE) \
+(GET_MODE_SIZE (MODE) <= UNITS_PER_WORD ? 6 : 12)
+
+/* The cost of a branch insn. */
+/* A value of 2 here causes GCC to avoid using branches in comparisons like
+ while (a < N && a). Branches aren't that expensive on the M32R so
+ we define this as 1. Defining it as 2 had a heavy hit in fp-bit.c. */
+#define BRANCH_COST 1
+
+/* Provide the costs of a rtl expression. This is in the body of a
+ switch on CODE. The purpose for the cost of MULT is to encourage
+ `synth_mult' to find a synthetic multiply when reasonable.
+
+ If we need more than 12 insns to do a multiply, then go out-of-line,
+ since the call overhead will be < 10% of the cost of the multiply. */
+#define RTX_COSTS(X, CODE, OUTER_CODE) \
+ case MULT : \
+ return COSTS_N_INSNS (3); \
+ case DIV : \
+ case UDIV : \
+ case MOD : \
+ case UMOD : \
+ return COSTS_N_INSNS (10); \
+
+/* Nonzero if access to memory by bytes is slow and undesirable.
+ For RISC chips, it means that access to memory by bytes is no
+ better than access by words when possible, so grab a whole word
+ and maybe make use of that. */
+#define SLOW_BYTE_ACCESS 1
+
+/* Define this macro if it is as good or better to call a constant
+ function address than to call an address kept in a register. */
+#define NO_FUNCTION_CSE
+
+/* Define this macro if it is as good or better for a function to call
+ itself with an explicit address than to call an address kept in a
+ register. */
+#define NO_RECURSIVE_FUNCTION_CSE
+
+/* Enable the register move pass.
+ This is useful for machines with only 2 address instructions.
+ It's not currently enabled by default because on the stanford benchmarks
+ the improvement wasn't significant and in a couple of cases caused a
+ significant de-optimization. */
+/* #define ENABLE_REGMOVE_PASS */
+
+/* Section selection. */
+
+#define TEXT_SECTION_ASM_OP "\t.section .text"
+#define DATA_SECTION_ASM_OP "\t.section .data"
+#define RODATA_SECTION_ASM_OP "\t.section .rodata"
+#define BSS_SECTION_ASM_OP "\t.section .bss"
+#define SDATA_SECTION_ASM_OP "\t.section .sdata"
+#define SBSS_SECTION_ASM_OP "\t.section .sbss"
+/* This one is for svr4.h. */
+#undef CONST_SECTION_ASM_OP
+#define CONST_SECTION_ASM_OP "\t.section .rodata"
+
+/* 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_sdata, in_sbss, in_const, in_ctors, in_dtors
+
+/* One or more functions to be defined in "varasm.c". These
+ functions should do jobs analogous to those of `text_section' and
+ `data_section', for your additional sections. Do not define this
+ macro if you do not define `EXTRA_SECTIONS'. */
+#undef EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS \
+CONST_SECTION_FUNCTION \
+CTORS_SECTION_FUNCTION \
+DTORS_SECTION_FUNCTION \
+SDATA_SECTION_FUNCTION \
+SBSS_SECTION_FUNCTION
+
+#define SDATA_SECTION_FUNCTION \
+void \
+sdata_section () \
+{ \
+ if (in_section != in_sdata) \
+ { \
+ fprintf (asm_out_file, "%s\n", SDATA_SECTION_ASM_OP); \
+ in_section = in_sdata; \
+ } \
+} \
+
+#define SBSS_SECTION_FUNCTION \
+void \
+sbss_section () \
+{ \
+ if (in_section != in_sbss) \
+ { \
+ fprintf (asm_out_file, "%s\n", SBSS_SECTION_ASM_OP); \
+ in_section = in_sbss; \
+ } \
+} \
+
+/* A C statement or statements to switch to the appropriate section for
+ output of EXP. You can assume that EXP is either a `VAR_DECL' node
+ or a constant of some sort. RELOC indicates whether the initial value
+ of EXP requires link-time relocations. */
+extern void m32r_select_section ();
+#undef SELECT_SECTION
+#define SELECT_SECTION(EXP, RELOC) m32r_select_section ((EXP), (RELOC))
+
+/* A C statement or statements to switch to the appropriate section for
+ output of RTX in mode MODE. You can assume that RTX
+ is some kind of constant in RTL. The argument MODE is redundant
+ except in the case of a `const_int' rtx. Select the section by
+ calling `text_section' or one of the alternatives for other
+ sections.
+
+ Do not define this macro if you put all constants in the read-only
+ data section. */
+
+#undef SELECT_RTX_SECTION
+
+/* Define this macro if jump tables (for tablejump insns) should be
+ output in the text section, along with the assembler instructions.
+ Otherwise, the readonly data section is used.
+ This macro is irrelevant if there is no separate readonly data section. */
+/*#define JUMP_TABLES_IN_TEXT_SECTION*/
+
+/* 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 or other node is created.
+ 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 store 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). */
+
+#define SDATA_FLAG_CHAR '@'
+/* Small objects are recorded with no prefix for space efficiency since
+ they'll be the most common. This isn't the case if the user passes
+ -mmodel={medium|large} and one could choose to not mark symbols that
+ are the default, but that complicates things. */
+/*#define SMALL_FLAG_CHAR '#'*/
+#define MEDIUM_FLAG_CHAR '%'
+#define LARGE_FLAG_CHAR '&'
+
+#define SDATA_NAME_P(NAME) (*(NAME) == SDATA_FLAG_CHAR)
+/*#define SMALL_NAME_P(NAME) (*(NAME) == SMALL_FLAG_CHAR)*/
+#define SMALL_NAME_P(NAME) (! ENCODED_NAME_P (NAME) && ! LIT_NAME_P (NAME))
+#define MEDIUM_NAME_P(NAME) (*(NAME) == MEDIUM_FLAG_CHAR)
+#define LARGE_NAME_P(NAME) (*(NAME) == LARGE_FLAG_CHAR)
+/* For string literals, etc. */
+#define LIT_NAME_P(NAME) ((NAME)[0] == '*' && (NAME)[1] == '.')
+
+#define ENCODED_NAME_P(SYMBOL_NAME) \
+(SDATA_NAME_P (SYMBOL_NAME) \
+ /*|| SMALL_NAME_P (SYMBOL_NAME)*/ \
+ || MEDIUM_NAME_P (SYMBOL_NAME) \
+ || LARGE_NAME_P (SYMBOL_NAME))
+
+extern void m32r_encode_section_info ();
+#define ENCODE_SECTION_INFO(DECL) m32r_encode_section_info (DECL)
+
+/* Decode SYM_NAME and store the real name part in VAR, sans
+ the characters that encode section info. Define this macro if
+ ENCODE_SECTION_INFO alters the symbol's name string. */
+/* Note that we have to handle symbols like "%*start". */
+#define STRIP_NAME_ENCODING(VAR, SYMBOL_NAME) \
+do { \
+ (VAR) = (SYMBOL_NAME) + ENCODED_NAME_P (SYMBOL_NAME); \
+ (VAR) += *(VAR) == '*'; \
+} while (0)
+
+/* PIC */
+
+/* The register number of the register used to address a table of static
+ data addresses in memory. In some cases this register is defined by a
+ processor's ``application binary interface'' (ABI). When this macro
+ is defined, RTL is generated for this register once, as with the stack
+ pointer and frame pointer registers. If this macro is not defined, it
+ is up to the machine-dependent files to allocate such a register (if
+ necessary). */
+/*#define PIC_OFFSET_TABLE_REGNUM 12*/
+
+/* Define this macro if the register defined by PIC_OFFSET_TABLE_REGNUM is
+ clobbered by calls. Do not define this macro if PIC_OFFSET_TABLE_REGNUM
+ is not defined. */
+/* This register is call-saved on the M32R. */
+/*#define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED*/
+
+/* By generating position-independent code, when two different programs (A
+ and B) share a common library (libC.a), the text of the library can be
+ shared whether or not the library is linked at the same address for both
+ programs. In some of these environments, position-independent code
+ requires not only the use of different addressing modes, but also
+ special code to enable the use of these addressing modes.
+
+ 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 m32r_finalize_pic ()*/
+
+/* A C expression that is nonzero if X is a legitimate immediate
+ operand on the target machine when generating position independent code.
+ You can assume that X satisfies CONSTANT_P, so you need not
+ check this. You can also assume `flag_pic' is true, so you need not
+ check it either. You need not define this macro if all constants
+ (including SYMBOL_REF) can be immediate operands when generating
+ position independent code. */
+/*#define LEGITIMATE_PIC_OPERAND_P(X)*/
+
+/* Control the assembler format that we output. */
+
+/* Output at beginning of assembler file. */
+extern void m32r_asm_file_start ();
+#define ASM_FILE_START(FILE) m32r_asm_file_start (FILE)
+
+/* A C string constant describing how to begin a comment in the target
+ assembler language. The compiler assumes that the comment will
+ end at the end of the line. */
+#define ASM_COMMENT_START ";"
+
+/* Output to assembler file text saying following lines
+ may contain character constants, extra white space, comments, etc. */
+#define ASM_APP_ON ""
+
+/* Output to assembler file text saying following lines
+ no longer contain unusual constructs. */
+#define ASM_APP_OFF ""
+
+/* This is how to output an assembler line defining a `char' constant. */
+#define ASM_OUTPUT_CHAR(FILE, VALUE) \
+do { \
+ fprintf (FILE, "\t.byte\t"); \
+ output_addr_const (FILE, (VALUE)); \
+ fprintf (FILE, "\n"); \
+} while (0)
+
+/* This is how to output an assembler line defining a `short' constant. */
+#define ASM_OUTPUT_SHORT(FILE, VALUE) \
+do { \
+ fprintf (FILE, "\t.hword\t"); \
+ output_addr_const (FILE, (VALUE)); \
+ fprintf (FILE, "\n"); \
+} while (0)
+
+/* This is how to output an assembler line defining an `int' constant.
+ We also handle symbol output here. */
+#define ASM_OUTPUT_INT(FILE, VALUE) \
+do { \
+ fprintf (FILE, "\t.word\t"); \
+ output_addr_const (FILE, (VALUE)); \
+ fprintf (FILE, "\n"); \
+} while (0)
+
+/* This is how to output an assembler line defining a `float' constant. */
+#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
+do { \
+ long t; \
+ char str[30]; \
+ REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \
+ fprintf (FILE, "\t.word\t0x%lx %s %s\n", \
+ t, ASM_COMMENT_START, str); \
+} while (0)
+
+/* This is how to output an assembler line defining a `double' constant. */
+#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
+do { \
+ long t[2]; \
+ char str[30]; \
+ REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \
+ fprintf (FILE, "\t.word\t0x%lx %s %s\n\t.word\t0x%lx\n", \
+ t[0], ASM_COMMENT_START, str, t[1]); \
+} while (0)
+
+/* This is how to output an assembler line for a numeric constant byte. */
+#define ASM_OUTPUT_BYTE(FILE, VALUE) \
+ fprintf (FILE, "\t%s\t0x%x\n", ASM_BYTE_OP, (VALUE))
+
+/* The assembler's parentheses characters. */
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
+
+/* 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. */
+/* On the M32R we need to ensure the next instruction starts on a 32 bit
+ boundary [the previous insn must either be 2 16 bit insns or 1 32 bit]. */
+#define ASM_OUTPUT_LABEL(FILE, NAME) \
+do { \
+ assemble_name (FILE, NAME); \
+ fputs (":\n", FILE); \
+} while (0)
+
+/* 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) \
+do { \
+ fputs ("\t.global\t", FILE); \
+ assemble_name (FILE, NAME); \
+ fputs ("\n", FILE); \
+} while (0)
+
+/* This is how to output a reference to a user-level label named NAME.
+ `assemble_name' uses this. */
+#undef ASM_OUTPUT_LABELREF
+#define ASM_OUTPUT_LABELREF(FILE, NAME) \
+do { \
+ char *real_name; \
+ STRIP_NAME_ENCODING (real_name, (NAME)); \
+ fprintf (FILE, "%s%s", USER_LABEL_PREFIX, real_name); \
+} 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) \
+do { \
+ (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10); \
+ sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)); \
+} while (0)
+
+/* How to refer to registers in assembler output.
+ This sequence is indexed by compiler's hard-register-number (see above). */
+#define REGISTER_NAMES \
+{ \
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", "r12", "fp", "lr", "sp", \
+ "ap", "cbit" \
+}
+
+/* If defined, a C initializer for an array of structures containing
+ a name and a register number. This macro defines additional names
+ for hard registers, thus allowing the `asm' option in declarations
+ to refer to registers using alternate names. */
+#define ADDITIONAL_REGISTER_NAMES \
+{ \
+ /*{ "gp", GP_REGNUM },*/ \
+ { "r13", FRAME_POINTER_REGNUM }, \
+ { "r14", RETURN_ADDR_REGNUM }, \
+ { "r15", STACK_POINTER_REGNUM }, \
+}
+
+/* A C expression which evaluates to true if CODE is a valid
+ punctuation character for use in the `PRINT_OPERAND' macro. */
+extern char m32r_punct_chars[];
+#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
+m32r_punct_chars[(unsigned char) (CHAR)]
+
+/* 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.
+ For `%' followed by punctuation, CODE is the punctuation and X is null. */
+#define PRINT_OPERAND(FILE, X, CODE) \
+m32r_print_operand (FILE, X, CODE)
+
+/* A C compound statement to output to stdio stream STREAM the
+ assembler syntax for an instruction operand that is a memory
+ reference whose address is ADDR. ADDR is an RTL expression.
+
+ On some machines, the syntax for a symbolic address depends on
+ the section that the address refers to. On these machines,
+ define the macro `ENCODE_SECTION_INFO' to store the information
+ into the `symbol_ref', and then check for it here. */
+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
+m32r_print_operand_address (FILE, ADDR)
+
+/* If defined, C string expressions to be used for the `%R', `%L',
+ `%U', and `%I' options of `asm_fprintf' (see `final.c'). These
+ are useful when a single `md' file must support multiple assembler
+ formats. In that case, the various `tm.h' files can define these
+ macros differently. */
+#define REGISTER_PREFIX ""
+#define LOCAL_LABEL_PREFIX ".L"
+#define USER_LABEL_PREFIX ""
+#define IMMEDIATE_PREFIX "#"
+
+/* This is how to output an element of a case-vector that is absolute. */
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
+do { \
+ char label[30]; \
+ ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \
+ fprintf (FILE, "\t.word\t"); \
+ assemble_name (FILE, label); \
+ fprintf (FILE, "\n"); \
+} while (0)
+
+/* This is how to output an element of a case-vector that is relative. */
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
+do { \
+ char label[30]; \
+ ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \
+ fprintf (FILE, "\t.word\t"); \
+ assemble_name (FILE, label); \
+ fprintf (FILE, "-"); \
+ ASM_GENERATE_INTERNAL_LABEL (label, "L", REL); \
+ assemble_name (FILE, label); \
+ fprintf (FILE, ")\n"); \
+} while (0)
+
+/* A C expression to output text to align the location counter in the way
+ that is desirable at the beginning of a loop. */
+/* On the M32R, align loops to 32 byte boundaries (cache line size)
+ if -malign-loops. */
+#define ASM_OUTPUT_LOOP_ALIGN(FILE) \
+do { if (TARGET_ALIGN_LOOPS) ASM_OUTPUT_ALIGN (FILE, 5); } while (0)
+
+/* This is how to output an assembler line
+ that says to advance the location counter
+ to a multiple of 2**LOG bytes. */
+/* .balign is used to avoid confusion. */
+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
+do { if ((LOG) != 0) fprintf (FILE, "\t.balign %d\n", 1 << (LOG)); } while (0)
+
+/* Like `ASM_OUTPUT_COMMON' except takes the required alignment as a
+ separate, explicit argument. If you define this macro, it is used in
+ place of `ASM_OUTPUT_COMMON', and gives you more flexibility in
+ handling the required alignment of the variable. The alignment is
+ specified as the number of bits. */
+
+#define SCOMMON_ASM_OP ".scomm"
+
+#undef ASM_OUTPUT_ALIGNED_COMMON
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
+do { \
+ if (! TARGET_SDATA_NONE \
+ && (SIZE) > 0 && (SIZE) <= g_switch_value) \
+ fprintf ((FILE), "\t%s\t", SCOMMON_ASM_OP); \
+ else \
+ fprintf ((FILE), "\t%s\t", COMMON_ASM_OP); \
+ assemble_name ((FILE), (NAME)); \
+ fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
+} while (0)
+
+#if 0 /* not needed, delete later */
+/* Like `ASM_OUTPUT_LOCAL' except takes the required alignment as a
+ separate, explicit argument. If you define this macro, it is used in
+ place of `ASM_OUTPUT_LOCAL', and gives you more flexibility in
+ handling the required alignment of the variable. The alignment is
+ specified as the number of bits. */
+
+extern void sbss_section ();
+
+#undef ASM_OUTPUT_ALIGNED_LOCAL
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
+do { \
+ if ((SIZE) > 0 && (SIZE) <= g_switch_value) \
+ { \
+ sbss_section (); \
+ ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT)); \
+ ASM_OUTPUT_LABEL (FILE, NAME); \
+ ASM_OUTPUT_SKIP (FILE, SIZE); \
+ if (!flag_inhibit_size_directive) \
+ { \
+ fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, ",%d\n", SIZE); \
+ } \
+ } \
+ else \
+ { \
+ /* This is copied from svr4.h. */ \
+ fprintf ((FILE), "\t%s\t", LOCAL_ASM_OP); \
+ assemble_name ((FILE), (NAME)); \
+ fprintf ((FILE), "\n"); \
+ ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \
+ } \
+} while (0)
+#endif
+
+/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a
+ separate, explicit argument. If you define this macro, it is used in
+ place of `ASM_OUTPUT_BSS', and gives you more flexibility in
+ handling the required alignment of the variable. The alignment is
+ specified as the number of bits.
+
+ For the M32R we need sbss support. */
+
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+do { \
+ ASM_GLOBALIZE_LABEL (FILE, NAME); \
+ ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \
+} while (0)
+
+/* Debugging information. */
+
+/* Generate DBX and DWARF debugging information. */
+#define DBX_DEBUGGING_INFO
+#define DWARF_DEBUGGING_INFO
+
+/* Prefer STABS (for now). */
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+/* How to renumber registers for dbx and gdb. */
+#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+
+/* Turn off splitting of long stabs. */
+#define DBX_CONTIN_LENGTH 0
+
+/* Miscellaneous. */
+
+/* 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. */
+/* It's not clear what PIC will look like or whether we want to use -fpic
+ for the embedded form currently being talked about. For now require -fpic
+ to get pc relative switch tables. */
+/*#define CASE_VECTOR_PC_RELATIVE*/
+
+/* Define if operations between registers always perform the operation
+ on the full register even if a narrower mode is specified. */
+#define WORD_REGISTER_OPERATIONS
+
+/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
+ will either zero-extend or sign-extend. The value of this macro should
+ be the code that says which one of the two operations is implicitly
+ done, NIL if none. */
+#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
+
+/* Specify the tree operation to be used to convert reals to integers. */
+#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
+
+/* Max number of bytes we can move from memory to memory
+ in one reasonably fast instruction. */
+#define MOVE_MAX 4
+
+/* Define this to be nonzero if shift instructions ignore all but the low-order
+ few bits. */
+#define SHIFT_COUNT_TRUNCATED 1
+
+/* 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
+
+/* 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. */
+/* ??? The M32R doesn't have full 32 bit pointers, but making this PSImode has
+ it's own problems (you have to add extendpsisi2 and truncsipsi2).
+ Try to avoid it. */
+#define Pmode SImode
+
+/* A function address in a call instruction. */
+#define FUNCTION_MODE SImode
+
+/* 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 TYPE. */
+extern int m32r_valid_machine_attribute ();
+#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
+m32r_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
+
+/* A C expression that returns 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). */
+extern int m32r_comp_type_attributes ();
+#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
+m32r_comp_type_attributes (TYPE1, TYPE2)
+
+/* Give newly defined TYPE some default attributes. */
+extern void m32r_set_default_type_attributes ();
+#define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \
+m32r_set_default_type_attributes (TYPE)
+
+/* 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 *m32r_compare_op0, *m32r_compare_op1;
+
+/* Define the function that build the compare insn for scc and bcc. */
+extern struct rtx_def *gen_compare ();
+
+/* M32R function types. */
+enum m32r_function_type {
+ M32R_FUNCTION_UNKNOWN, M32R_FUNCTION_NORMAL, M32R_FUNCTION_INTERRUPT
+};
+#define M32R_INTERRUPT_P(TYPE) \
+((TYPE) == M32R_FUNCTION_INTERRUPT)
+/* Compute the type of a function from its DECL. */
+enum m32r_function_type m32r_compute_function_type ();
diff --git a/gnu/usr.bin/gcc/config/m32r/m32r.md b/gnu/usr.bin/gcc/config/m32r/m32r.md
new file mode 100644
index 00000000000..4c8b2e54ffb
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m32r/m32r.md
@@ -0,0 +1,1469 @@
+;; Machine description of the Mitsubishi M32R cpu for GNU C compiler
+;; Copyright (C) 1996, 1997 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.
+
+;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
+
+;; unspec usage
+;; 0 - blockage
+;; 1 - flush_icache
+;; 2 - load_sda_base
+
+;; Insn type. Used to default other attribute values.
+;; move4 = 4 byte move
+(define_attr "type"
+ "move,move4,load,store,unary,binary,compare,shift,mul,div,uncond_branch,branch,call,multi,misc"
+ (const_string "misc"))
+
+;; Length in bytes.
+(define_attr "length" ""
+ (cond [(eq_attr "type" "move,unary,shift,mul,div")
+ (const_int 2)
+
+ (eq_attr "type" "binary")
+ (if_then_else (match_operand 2 "register_operand" "")
+ (const_int 2) (const_int 4))
+
+ (eq_attr "type" "compare")
+ (if_then_else (match_operand 1 "register_operand" "")
+ (const_int 2) (const_int 4))
+
+ (eq_attr "type" "load")
+ (if_then_else (match_operand 1 "memreg_operand" "")
+ (const_int 2) (const_int 4))
+
+ (eq_attr "type" "store")
+ (if_then_else (match_operand 0 "memreg_operand" "")
+ (const_int 2) (const_int 4))
+
+ (eq_attr "type" "multi")
+ (const_int 8)
+
+ (eq_attr "type" "uncond_branch,branch,call")
+ (const_int 4)]
+
+ (const_int 4)))
+
+;; The length here is the length of a single asm. Unfortunately it might be
+;; 2 or 4 so we must allow for 4. That's ok though.
+(define_asm_attributes
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")])
+
+;; Function units of the M32R
+;; Units that take one cycle do not need to be specified.
+
+;; (define_function_unit {name} {num-units} {n-users} {test}
+;; {ready-delay} {issue-delay} [{conflict-list}])
+
+;; References to loaded registers should wait a cycle.
+;; Memory with load-delay of 1 (i.e. 2 cycle load).
+(define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0)
+
+;; Hack to get GCC to better pack the instructions.
+;; We pretend there is a separate long function unit that conflicts with
+;; both the left and right 16 bit insn slots.
+
+(define_function_unit "left" 1 1
+ (eq_attr "length" "2")
+ 1 0
+ [(not (eq_attr "length" "2"))])
+
+(define_function_unit "right" 1 1
+ (eq_attr "length" "1")
+ 1 0
+ [(not (eq_attr "length" "2"))])
+
+(define_function_unit "long" 1 1
+ (not (eq_attr "length" "2"))
+ 1 0
+ [(eq_attr "length" "2")])
+
+;; Expand prologue as RTL
+;; ??? Unfinished.
+
+;(define_expand "prologue"
+; [(const_int 1)]
+; ""
+; "
+;{
+;}")
+
+;; Move instructions.
+;;
+;; For QI and HI moves, the register must contain the full properly
+;; sign-extended value. nonzero_bits assumes this [otherwise
+;; SHORT_IMMEDIATES_SIGN_EXTEND must be used, but the comment for it
+;; says it's a kludge and the .md files should be fixed instead].
+
+(define_expand "movqi"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (match_operand:QI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* Everything except mem = const or mem = mem can be done easily.
+ Objects in the small data area are handled too. */
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (QImode, operands[1]);
+}")
+
+(define_insn "*movqi_insn"
+ [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,r,m")
+ (match_operand:QI 1 "move_src_operand" "r,I,JQR,m,r"))]
+ "register_operand (operands[0], QImode) || register_operand (operands[1], QImode)"
+ "@
+ mv %0,%1
+ ldi %0,%#%1
+ ldi %0,%#%1
+ ldub %0,%1
+ stb %1,%0"
+ [(set_attr "type" "move,move,move4,load,store")])
+
+(define_expand "movhi"
+ [(set (match_operand:HI 0 "general_operand" "")
+ (match_operand:HI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* Everything except mem = const or mem = mem can be done easily. */
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (HImode, operands[1]);
+}")
+
+(define_insn "*movhi_insn"
+ [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,r,r,m")
+ (match_operand:HI 1 "move_src_operand" "r,I,JQR,K,m,r"))]
+ "register_operand (operands[0], HImode) || register_operand (operands[1], HImode)"
+ "@
+ mv %0,%1
+ ldi %0,%#%1
+ ldi %0,%#%1
+ ld24 %0,%#%1
+ lduh %0,%1
+ sth %1,%0"
+ [(set_attr "type" "move,move,move4,move4,load,store")])
+
+(define_expand "movsi"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (match_operand:SI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* Everything except mem = const or mem = mem can be done easily. */
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (SImode, operands[1]);
+
+ /* Small Data Area reference? */
+ if (small_data_operand (operands[1], SImode))
+ {
+ emit_insn (gen_movsi_sda (operands[0], operands[1]));
+ DONE;
+ }
+
+ /* If medium or large code model, symbols have to be loaded with
+ seth/add3. */
+ if (addr32_operand (operands[1], SImode))
+ {
+ emit_insn (gen_movsi_addr32 (operands[0], operands[1]));
+ DONE;
+ }
+}")
+
+(define_insn "*movsi_insn"
+ [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,r,r,r,r,m")
+;; ??? Do we need a const_double constraint here for large unsigned values?
+ (match_operand:SI 1 "move_src_operand" "r,I,J,MQ,L,N,m,r"))]
+ "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)"
+ "@
+ mv %0,%1
+ ldi %0,%#%1 ; %X1
+ ldi %0,%#%1 ; %X1
+ ld24 %0,%#%1 ; %X1
+ seth %0,%#%T1
+ seth %0,%#%T1\;or3 %0,%0,%#%B1
+ ld %0,%1
+ st %1,%0"
+ [(set_attr "type" "move,move,move4,move4,move4,multi,load,store")])
+
+; Try to use a four byte / two byte pair for constants not loadable with
+; ldi, ld24, seth.
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "two_insn_const_operand" ""))]
+ ""
+ [(set (match_dup 0) (match_dup 2))
+ (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 3)))]
+ "
+{
+ unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
+ unsigned HOST_WIDE_INT tmp;
+ int shift;
+
+ /* In all cases we will emit two instructions. However we try to
+ use 2 byte instructions wherever possible. We can assume the
+ constant isn't loadable with any of ldi, ld24, or seth. */
+
+ /* See if we can load a 24 bit unsigned value and invert it. */
+ if (UINT24_P (~ val))
+ {
+ emit_insn (gen_movsi (operands[0], GEN_INT (~ val)));
+ emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
+ DONE;
+ }
+
+ /* See if we can load a 24 bit unsigned value and shift it into place.
+ 0x01fffffe is just beyond ld24's range. */
+ for (shift = 1, tmp = 0x01fffffe;
+ shift < 8;
+ ++shift, tmp <<= 1)
+ {
+ if ((val & ~tmp) == 0)
+ {
+ emit_insn (gen_movsi (operands[0], GEN_INT (val >> shift)));
+ emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (shift)));
+ DONE;
+ }
+ }
+
+ /* Can't use any two byte insn, fall back to seth/or3. */
+ operands[2] = GEN_INT ((val) & 0xffff0000);
+ operands[3] = GEN_INT ((val) & 0xffff);
+}")
+
+;; Small data area support.
+;; The address of _SDA_BASE_ is loaded into a register and all objects in
+;; the small data area are indexed off that. This is done for each reference
+;; but cse will clean things up for us. We let the compiler choose the
+;; register to use so we needn't allocate (and maybe even fix) a special
+;; register to use. Since the load and store insns have a 16 bit offset the
+;; total size of the data area can be 64K. However, if the data area lives
+;; above 16M (24 bits), _SDA_BASE_ will have to be loaded with seth/add3 which
+;; would then yield 3 instructions to reference an object [though there would
+;; be no net loss if two or more objects were referenced]. The 3 insns can be
+;; reduced back to 2 if the size of the small data area were reduced to 32K
+;; [then seth + ld/st would work for any object in the area]. Doing this
+;; would require special handling of _SDA_BASE_ (its value would be
+;; (.sdata + 32K) & 0xffff0000) and reloc computations would be different
+;; [I think]. What to do about this is deferred until later and for now we
+;; require .sdata to be in the first 16M.
+
+(define_expand "movsi_sda"
+ [(set (match_dup 2)
+ (unspec [(const_int 0)] 2))
+ (set (match_operand:SI 0 "register_operand" "")
+ (lo_sum:SI (match_dup 2)
+ (match_operand:SI 1 "small_data_operand" "")))]
+ ""
+ "
+{
+ if (reload_in_progress || reload_completed)
+ operands[2] = operands[0];
+ else
+ operands[2] = gen_reg_rtx (SImode);
+}")
+
+(define_insn "*load_sda_base"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec [(const_int 0)] 2))]
+ ""
+ "ld24 %0,#_SDA_BASE_"
+ [(set_attr "type" "move4")])
+
+;; 32 bit address support.
+
+(define_expand "movsi_addr32"
+ [(set (match_dup 2)
+ ; addr32_operand isn't used because it's too restrictive,
+ ; seth_add3_operand is more general and thus safer.
+ (high:SI (match_operand:SI 1 "seth_add3_operand" "")))
+ (set (match_operand:SI 0 "register_operand" "")
+ (lo_sum:SI (match_dup 2) (match_dup 1)))]
+ ""
+ "
+{
+ if (reload_in_progress || reload_completed)
+ operands[2] = operands[0];
+ else
+ operands[2] = gen_reg_rtx (SImode);
+}")
+
+(define_insn "set_hi_si"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (match_operand 1 "symbolic_operand" "")))]
+ ""
+ "seth %0,%#shigh(%1)"
+ [(set_attr "type" "move4")])
+
+(define_insn "lo_sum_si"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "immediate_operand" "in")))]
+ ""
+ "add3 %0,%1,%#%B2"
+ [(set_attr "length" "4")])
+
+(define_expand "movdi"
+ [(set (match_operand:DI 0 "general_operand" "")
+ (match_operand:DI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* Everything except mem = const or mem = mem can be done easily. */
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (DImode, operands[1]);
+
+ if (CONSTANT_P (operands[1])
+ && ! easy_di_const (operands[1]))
+ {
+ rtx mem = force_const_mem (DImode, operands[1]);
+ rtx reg = ((reload_in_progress || reload_completed)
+ ? copy_to_suggested_reg (XEXP (mem, 0),
+ gen_rtx (REG, Pmode, REGNO (operands[0])),
+ Pmode)
+ : force_reg (Pmode, XEXP (mem, 0)));
+ operands[1] = change_address (mem, DImode, reg);
+ }
+}")
+
+(define_insn "*movdi_insn"
+ [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,m")
+ (match_operand:DI 1 "move_double_src_operand" "r,nG,m,r"))]
+ "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0 :
+ /* We normally copy the low-numbered register first. However, if
+ the first register operand 0 is the same as the second register of
+ operand 1, we must copy in the opposite order. */
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"mv %R0,%R1\;mv %0,%1\";
+ else
+ return \"mv %0,%1\;mv %R0,%R1\";
+ case 1 :
+ return \"#\";
+ case 2 :
+ /* If the low-address word is used in the address, we must load it
+ last. Otherwise, load it first. Note that we cannot have
+ auto-increment in that case since the address register is known to be
+ dead. */
+ if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
+ operands [1], 0))
+ {
+ return \"ld %R0,%R1\;ld %0,%1\";
+ }
+ else
+ {
+ /* Try to use auto-inc addressing if we can. */
+ if (GET_CODE (XEXP (operands[1], 0)) == REG
+ && dead_or_set_p (insn, XEXP (operands[1], 0)))
+ {
+ operands[1] = XEXP (operands[1], 0);
+ return \"ld %0,@%1+\;ld %R0,@%1\";
+ }
+ return \"ld %0,%1\;ld %R0,%R1\";
+ }
+ case 3 :
+ /* Try to use auto-inc addressing if we can. */
+ if (GET_CODE (XEXP (operands[0], 0)) == REG
+ && dead_or_set_p (insn, XEXP (operands[0], 0)))
+ {
+ operands[0] = XEXP (operands[0], 0);
+ return \"st %1,@%0\;st %R1,@+%0\";
+ }
+ return \"st %1,%0\;st %R1,%R0\";
+ }
+}"
+ [(set_attr "type" "multi,multi,multi,multi")
+ (set_attr "length" "4,4,6,6")])
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "const_double_operand" ""))]
+ "reload_completed"
+ [(set (match_dup 2) (match_dup 4))
+ (set (match_dup 3) (match_dup 5))]
+ "
+{
+ operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
+ operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
+ split_double (operands[1], operands + 4, operands + 5);
+}")
+
+;; Floating point move insns.
+
+(define_expand "movsf"
+ [(set (match_operand:SF 0 "general_operand" "")
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* Everything except mem = const or mem = mem can be done easily. */
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (SFmode, operands[1]);
+}")
+
+(define_insn "*movsf_insn"
+ [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
+ (match_operand:SF 1 "move_src_operand" "r,F,m,r"))]
+ "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0 :
+ return \"mv %0,%1\";
+ case 1 :
+ {
+ REAL_VALUE_TYPE r;
+ long l;
+ REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
+ REAL_VALUE_TO_TARGET_SINGLE (r, l);
+ operands[1] = GEN_INT (l);
+ if (l == 0)
+ return \"ldi %0,%#0\";
+ if ((l & 0xffff) == 0)
+ return \"seth %0,%#%T1\";
+ else
+ return \"seth %0,%#%T1\;or3 %0,%0,%#%B1\";
+ }
+ case 2 :
+ return \"ld %0,%1\";
+ case 3 :
+ return \"st %1,%0\";
+ }
+}"
+ ;; ??? Length of alternative 1 is either 2, 4 or 8.
+ [(set_attr "type" "move,multi,load,store")])
+
+(define_expand "movdf"
+ [(set (match_operand:DF 0 "general_operand" "")
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* Everything except mem = const or mem = mem can be done easily. */
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (DFmode, operands[1]);
+
+ if (GET_CODE (operands[1]) == CONST_DOUBLE
+ && ! easy_df_const (operands[1]))
+ {
+ rtx mem = force_const_mem (DFmode, operands[1]);
+ rtx reg = ((reload_in_progress || reload_completed)
+ ? copy_to_suggested_reg (XEXP (mem, 0),
+ gen_rtx (REG, Pmode, REGNO (operands[0])),
+ Pmode)
+ : force_reg (Pmode, XEXP (mem, 0)));
+ operands[1] = change_address (mem, DFmode, reg);
+ }
+}")
+
+(define_insn "*movdf_insn"
+ [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
+ (match_operand:DF 1 "move_double_src_operand" "r,H,m,r"))]
+ "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0 :
+ /* We normally copy the low-numbered register first. However, if
+ the first register operand 0 is the same as the second register of
+ operand 1, we must copy in the opposite order. */
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"mv %R0,%R1\;mv %0,%1\";
+ else
+ return \"mv %0,%1\;mv %R0,%R1\";
+ case 1 :
+ {
+ REAL_VALUE_TYPE r;
+ long l[2];
+ REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
+ REAL_VALUE_TO_TARGET_DOUBLE (r, l);
+ operands[1] = GEN_INT (l[0]);
+ if (l[0] == 0 && l[1] == 0)
+ return \"ldi %0,%#0\;ldi %R0,%#0\";
+ else if (l[1] != 0)
+ abort ();
+ else if ((l[0] & 0xffff) == 0)
+ return \"seth %0,%#%T1\;ldi %R0,%#0\";
+ else
+ abort ();
+ }
+ case 2 :
+ /* If the low-address word is used in the address, we must load it
+ last. Otherwise, load it first. Note that we cannot have
+ auto-increment in that case since the address register is known to be
+ dead. */
+ if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
+ operands [1], 0))
+ {
+ return \"ld %R0,%R1\;ld %0,%1\";
+ }
+ else
+ {
+ /* Try to use auto-inc addressing if we can. */
+ if (GET_CODE (XEXP (operands[1], 0)) == REG
+ && dead_or_set_p (insn, XEXP (operands[1], 0)))
+ {
+ operands[1] = XEXP (operands[1], 0);
+ return \"ld %0,@%1+\;ld %R0,@%1\";
+ }
+ return \"ld %0,%1\;ld %R0,%R1\";
+ }
+ case 3 :
+ /* Try to use auto-inc addressing if we can. */
+ if (GET_CODE (XEXP (operands[0], 0)) == REG
+ && dead_or_set_p (insn, XEXP (operands[0], 0)))
+ {
+ operands[0] = XEXP (operands[0], 0);
+ return \"st %1,@%0\;st %R1,@+%0\";
+ }
+ return \"st %1,%0\;st %R1,%R0\";
+ }
+}"
+ [(set_attr "type" "multi,multi,multi,multi")
+ (set_attr "length" "4,6,6,6")])
+
+;; Zero extension instructions.
+
+(define_insn "zero_extendqihi2"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
+ ""
+ "@
+ and3 %0,%1,%#255
+ ldub %0,%1"
+ [(set_attr "type" "unary,load")
+ (set_attr "length" "4,*")])
+
+(define_insn "zero_extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
+ ""
+ "@
+ and3 %0,%1,%#255
+ ldub %0,%1"
+ [(set_attr "type" "unary,load")
+ (set_attr "length" "4,*")])
+
+(define_insn "zero_extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
+ ""
+ "@
+ and3 %0,%1,%#65535
+ lduh %0,%1"
+ [(set_attr "type" "unary,load")
+ (set_attr "length" "4,*")])
+
+;; Sign extension instructions.
+;; ??? See v850.md.
+
+;; These patterns originally accepted general_operands, however, slightly
+;; better code is generated by only accepting register_operands, and then
+;; letting combine generate the lds[hb] insns.
+;; [This comment copied from sparc.md, I think.]
+
+(define_expand "extendqihi2"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
+ ""
+ "
+{
+ rtx temp = gen_reg_rtx (SImode);
+ rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
+ int op1_subword = 0;
+ int op0_subword = 0;
+
+ if (GET_CODE (operand1) == SUBREG)
+ {
+ op1_subword = SUBREG_WORD (operand1);
+ operand1 = XEXP (operand1, 0);
+ }
+ if (GET_CODE (operand0) == SUBREG)
+ {
+ op0_subword = SUBREG_WORD (operand0);
+ operand0 = XEXP (operand0, 0);
+ }
+ emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
+ op1_subword),
+ shift_24));
+ if (GET_MODE (operand0) != SImode)
+ operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
+ emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
+ DONE;
+}")
+
+(define_insn "*sign_extendqihi2_insn"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
+ ""
+ "ldb %0,%1"
+ [(set_attr "type" "load")])
+
+(define_expand "extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
+ ""
+ "
+{
+ rtx temp = gen_reg_rtx (SImode);
+ rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
+ int op1_subword = 0;
+
+ if (GET_CODE (operand1) == SUBREG)
+ {
+ op1_subword = SUBREG_WORD (operand1);
+ operand1 = XEXP (operand1, 0);
+ }
+
+ emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
+ op1_subword),
+ shift_24));
+ emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
+ DONE;
+}")
+
+(define_insn "*sign_extendqisi2_insn"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
+ ""
+ "ldb %0,%1"
+ [(set_attr "type" "load")])
+
+(define_expand "extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
+ ""
+ "
+{
+ rtx temp = gen_reg_rtx (SImode);
+ rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
+ int op1_subword = 0;
+
+ if (GET_CODE (operand1) == SUBREG)
+ {
+ op1_subword = SUBREG_WORD (operand1);
+ operand1 = XEXP (operand1, 0);
+ }
+
+ emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
+ op1_subword),
+ shift_16));
+ emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
+ DONE;
+}")
+
+(define_insn "*sign_extendhisi2_insn"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
+ ""
+ "ldh %0,%1"
+ [(set_attr "type" "load")])
+
+;; Arithmetic instructions.
+
+; ??? Adding an alternative to split add3 of small constants into two
+; insns yields better instruction packing but slower code. Adds of small
+; values is done a lot.
+
+(define_insn "addsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (plus:SI (match_operand:SI 1 "register_operand" "%0,0,r")
+ (match_operand:SI 2 "nonmemory_operand" "r,I,J")))]
+ ""
+ "@
+ add %0,%2
+ addi %0,%#%2
+ add3 %0,%1,%#%2"
+ [(set_attr "type" "binary")
+ (set_attr "length" "2,2,4")])
+
+;(define_split
+; [(set (match_operand:SI 0 "register_operand" "")
+; (plus:SI (match_operand:SI 1 "register_operand" "")
+; (match_operand:SI 2 "int8_operand" "")))]
+; "reload_completed
+; && REGNO (operands[0]) != REGNO (operands[1])
+; && INT8_P (INTVAL (operands[2]))
+; && INTVAL (operands[2]) != 0"
+; [(set (match_dup 0) (match_dup 1))
+; (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
+; "")
+
+(define_insn "adddi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "%0")
+ (match_operand:DI 2 "register_operand" "r")))
+ (clobber (reg:CC 17))]
+ ""
+ "*
+{
+ /* ??? The cmp clears the condition bit. Can we speed up somehow? */
+ return \"cmp %L0,%L0\;addx %L0,%L2\;addx %H0,%H2\";
+}"
+ [(set_attr "type" "binary")
+ (set_attr "length" "6")])
+
+(define_insn "subsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (minus:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+ "sub %0,%2"
+ [(set_attr "type" "binary")])
+
+(define_insn "subdi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (minus:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:DI 2 "register_operand" "r")))
+ (clobber (reg:CC 17))]
+ ""
+ "*
+{
+ /* ??? The cmp clears the condition bit. Can we speed up somehow? */
+ return \"cmp %L0,%L0\;subx %L0,%L2\;subx %H0,%H2\";
+}"
+ [(set_attr "type" "binary")
+ (set_attr "length" "6")])
+
+; Multiply/Divide instructions.
+
+(define_insn "mulhisi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
+ (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
+ ""
+ "mullo %1,%2\;mvfacmi %0"
+ [(set_attr "type" "mul")
+ (set_attr "length" "4")])
+
+(define_insn "mulsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI (match_operand:SI 1 "register_operand" "%0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+ "mul %0,%2"
+ [(set_attr "type" "mul")])
+
+(define_insn "divsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (div:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+ "div %0,%2"
+ [(set_attr "type" "div")])
+
+(define_insn "udivsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (udiv:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+ "divu %0,%2"
+ [(set_attr "type" "div")])
+
+(define_insn "modsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mod:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+ "rem %0,%2"
+ [(set_attr "type" "div")])
+
+(define_insn "umodsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (umod:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+ "remu %0,%2"
+ [(set_attr "type" "div")])
+
+;; Boolean instructions.
+;;
+;; We don't define the DImode versions as expand_binop does a good enough job.
+;; And if it doesn't it should be fixed.
+
+(define_insn "andsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (and:SI (match_operand:SI 1 "register_operand" "%0,r")
+ (match_operand:SI 2 "nonmemory_operand" "r,K")))]
+ ""
+ "@
+ and %0,%2
+ and3 %0,%1,%#%2 ; %X2"
+ [(set_attr "type" "binary")])
+
+(define_insn "iorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (ior:SI (match_operand:SI 1 "register_operand" "%0,r")
+ (match_operand:SI 2 "nonmemory_operand" "r,K")))]
+ ""
+ "@
+ or %0,%2
+ or3 %0,%1,%#%2 ; %X2"
+ [(set_attr "type" "binary")])
+
+(define_insn "xorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (xor:SI (match_operand:SI 1 "register_operand" "%0,r")
+ (match_operand:SI 2 "nonmemory_operand" "r,K")))]
+ ""
+ "@
+ xor %0,%2
+ xor3 %0,%1,%#%2 ; %X2"
+ [(set_attr "type" "binary")])
+
+(define_insn "negsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (neg:SI (match_operand:SI 1 "register_operand" "r")))]
+ ""
+ "neg %0,%1"
+ [(set_attr "type" "unary")])
+
+(define_insn "one_cmplsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (not:SI (match_operand:SI 1 "register_operand" "r")))]
+ ""
+ "not %0,%1"
+ [(set_attr "type" "unary")])
+
+;; Shift instructions.
+
+(define_insn "ashlsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r")
+ (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
+ ""
+ "@
+ sll %0,%2
+ slli %0,%#%2
+ sll3 %0,%1,%#%2"
+ [(set_attr "type" "shift")
+ (set_attr "length" "2,2,4")])
+
+(define_insn "ashrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
+ (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
+ ""
+ "@
+ sra %0,%2
+ srai %0,%#%2
+ sra3 %0,%1,%#%2"
+ [(set_attr "type" "shift")
+ (set_attr "length" "2,2,4")])
+
+(define_insn "lshrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
+ (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
+ ""
+ "@
+ srl %0,%2
+ srli %0,%#%2
+ srl3 %0,%1,%#%2"
+ [(set_attr "type" "shift")
+ (set_attr "length" "2,2,4")])
+
+;; Compare instructions.
+;; This controls RTL generation and register allocation.
+
+;; We generate RTL for comparisons and branches by having the cmpxx
+;; patterns store away the operands. Then the bcc patterns
+;; emit RTL for both the compare and the branch.
+;;
+;; On the m32r it is more efficient to use the bxxz instructions and
+;; thus merge the compare and branch into one instruction, so they are
+;; preferred.
+
+(define_expand "cmpsi"
+ [(set (reg:CC 17)
+ (compare:CC (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "nonmemory_operand" "")))]
+ ""
+ "
+{
+ m32r_compare_op0 = operands[0];
+ m32r_compare_op1 = operands[1];
+ DONE;
+}")
+
+;; The cmp_xxx_insn patterns set the condition bit to the result of the
+;; comparison. There isn't a "compare equal" instruction so cmp_eqsi_insn
+;; is quite inefficient. However, it is rarely used.
+
+(define_insn "cmp_eqsi_insn"
+ [(set (reg:CC 17)
+ (eq:CC (match_operand:SI 0 "register_operand" "r,r")
+ (match_operand:SI 1 "reg_or_cmp_int16_operand" "r,P")))
+ (clobber (match_scratch:SI 2 "=&r,&r"))]
+ "TARGET_OLD_COMPARE"
+ "@
+ mv %2,%0\;sub %2,%1\;cmpui %2,#1
+ add3 %2,%0,%#%N1\;cmpui %2,#1"
+ [(set_attr "type" "compare,compare")
+ (set_attr "length" "8,8")])
+
+(define_insn "cmp_ltsi_insn"
+ [(set (reg:CC 17)
+ (lt:CC (match_operand:SI 0 "register_operand" "r,r")
+ (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
+ ""
+ "@
+ cmp %0,%1
+ cmpi %0,%#%1"
+ [(set_attr "type" "compare")])
+
+(define_insn "cmp_ltusi_insn"
+ [(set (reg:CC 17)
+ (ltu:CC (match_operand:SI 0 "register_operand" "r,r")
+ (match_operand:SI 1 "reg_or_uint16_operand" "r,K")))]
+ ""
+ "@
+ cmpu %0,%1
+ cmpui %0,%#%1"
+ [(set_attr "type" "compare")])
+
+;; reg == small constant comparisons are best handled by putting the result
+;; of the comparison in a tmp reg and then using beqz/bnez.
+;; ??? The result register doesn't contain 0/STORE_FLAG_VALUE,
+;; it contains 0/non-zero.
+
+(define_insn "cmp_ne_small_const_insn"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ne:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "cmp_int16_operand" "P")))]
+ ""
+ "add3 %0,%1,%#%N2"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4")])
+
+;; These control RTL generation for conditional jump insns.
+
+(define_expand "beq"
+ [(set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare (EQ, m32r_compare_op0, m32r_compare_op1);
+}")
+
+(define_expand "bne"
+ [(set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare (NE, m32r_compare_op0, m32r_compare_op1);
+}")
+
+(define_expand "bgt"
+ [(set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare (GT, m32r_compare_op0, m32r_compare_op1);
+}")
+
+(define_expand "ble"
+ [(set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare (LE, m32r_compare_op0, m32r_compare_op1);
+}")
+
+(define_expand "bge"
+ [(set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare (GE, m32r_compare_op0, m32r_compare_op1);
+}")
+
+(define_expand "blt"
+ [(set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare (LT, m32r_compare_op0, m32r_compare_op1);
+}")
+
+(define_expand "bgtu"
+ [(set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare (GTU, m32r_compare_op0, m32r_compare_op1);
+}")
+
+(define_expand "bleu"
+ [(set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare (LEU, m32r_compare_op0, m32r_compare_op1);
+}")
+
+(define_expand "bgeu"
+ [(set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare (GEU, m32r_compare_op0, m32r_compare_op1);
+}")
+
+(define_expand "bltu"
+ [(set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{
+ operands[1] = gen_compare (LTU, m32r_compare_op0, m32r_compare_op1);
+}")
+
+;; Now match both normal and inverted jump.
+
+(define_insn "*branch_insn"
+ [(set (pc)
+ (if_then_else (match_operator 1 "eqne_comparison_operator"
+ [(reg 17) (const_int 0)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ if (GET_CODE (operands[1]) == NE)
+ return \"bc %l0\";
+ else
+ return \"bnc %l0\";
+}"
+ [(set_attr "type" "branch")
+ ; We use 400/800 instead of 512,1024 to account for inaccurate insn
+ ; lengths and insn alignments that are complex to track.
+ ; It's not important that we be hyper-precise here. It may be more
+ ; important blah blah blah when the chip supports parallel execution
+ ; blah blah blah but until then blah blah blah this is simple and
+ ; suffices.
+ (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
+ (const_int 400))
+ (const_int 800))
+ (const_int 2)
+ (const_int 4)))])
+
+(define_insn "*rev_branch_insn"
+ [(set (pc)
+ (if_then_else (match_operator 1 "eqne_comparison_operator"
+ [(reg 17) (const_int 0)])
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ;"REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
+ ""
+ "*
+{
+ if (GET_CODE (operands[1]) == EQ)
+ return \"bc %l0\";
+ else
+ return \"bnc %l0\";
+}"
+ [(set_attr "type" "branch")
+ ; We use 400/800 instead of 512,1024 to account for inaccurate insn
+ ; lengths and insn alignments that are complex to track.
+ ; It's not important that we be hyper-precise here. It may be more
+ ; important blah blah blah when the chip supports parallel execution
+ ; blah blah blah but until then blah blah blah this is simple and
+ ; suffices.
+ (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
+ (const_int 400))
+ (const_int 800))
+ (const_int 2)
+ (const_int 4)))])
+
+; reg/reg compare and branch insns
+
+(define_insn "*reg_branch_insn"
+ [(set (pc)
+ (if_then_else (match_operator 1 "eqne_comparison_operator"
+ [(match_operand:SI 2 "register_operand" "r")
+ (match_operand:SI 3 "register_operand" "r")])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ /* Is branch target reachable with beq/bne? */
+ if (get_attr_length (insn) == 4)
+ {
+ if (GET_CODE (operands[1]) == EQ)
+ return \"beq %2,%3,%l0\";
+ else
+ return \"bne %2,%3,%l0\";
+ }
+ else
+ {
+ if (GET_CODE (operands[1]) == EQ)
+ return \"bne %2,%3,1f\;bra %l0\;1:\";
+ else
+ return \"beq %2,%3,1f\;bra %l0\;1:\";
+ }
+}"
+ [(set_attr "type" "branch")
+ ; We use 25000/50000 instead of 32768/65536 to account for slot filling
+ ; which is complex to track and inaccurate length specs.
+ (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
+ (const_int 25000))
+ (const_int 50000))
+ (const_int 4)
+ (const_int 8)))])
+
+(define_insn "*rev_reg_branch_insn"
+ [(set (pc)
+ (if_then_else (match_operator 1 "eqne_comparison_operator"
+ [(match_operand:SI 2 "register_operand" "r")
+ (match_operand:SI 3 "register_operand" "r")])
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ /* Is branch target reachable with beq/bne? */
+ if (get_attr_length (insn) == 4)
+ {
+ if (GET_CODE (operands[1]) == NE)
+ return \"beq %2,%3,%l0\";
+ else
+ return \"bne %2,%3,%l0\";
+ }
+ else
+ {
+ if (GET_CODE (operands[1]) == NE)
+ return \"bne %2,%3,1f\;bra %l0\;1:\";
+ else
+ return \"beq %2,%3,1f\;bra %l0\;1:\";
+ }
+}"
+ [(set_attr "type" "branch")
+ ; We use 25000/50000 instead of 32768/65536 to account for slot filling
+ ; which is complex to track and inaccurate length specs.
+ (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
+ (const_int 25000))
+ (const_int 50000))
+ (const_int 4)
+ (const_int 8)))])
+
+; reg/zero compare and branch insns
+
+(define_insn "*zero_branch_insn"
+ [(set (pc)
+ (if_then_else (match_operator 1 "signed_comparison_operator"
+ [(match_operand:SI 2 "register_operand" "r")
+ (const_int 0)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ char *br,*invbr;
+ char asmtext[40];
+
+ switch (GET_CODE (operands[1]))
+ {
+ case EQ : br = \"eq\"; invbr = \"ne\"; break;
+ case NE : br = \"ne\"; invbr = \"eq\"; break;
+ case LE : br = \"le\"; invbr = \"gt\"; break;
+ case GT : br = \"gt\"; invbr = \"le\"; break;
+ case LT : br = \"lt\"; invbr = \"ge\"; break;
+ case GE : br = \"ge\"; invbr = \"lt\"; break;
+ }
+
+ /* Is branch target reachable with bxxz? */
+ if (get_attr_length (insn) == 4)
+ {
+ sprintf (asmtext, \"b%sz %%2,%%l0\", br);
+ output_asm_insn (asmtext, operands);
+ }
+ else
+ {
+ sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", invbr);
+ output_asm_insn (asmtext, operands);
+ }
+ return \"\";
+}"
+ [(set_attr "type" "branch")
+ ; We use 25000/50000 instead of 32768/65536 to account for slot filling
+ ; which is complex to track and inaccurate length specs.
+ (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
+ (const_int 25000))
+ (const_int 50000))
+ (const_int 4)
+ (const_int 8)))])
+
+(define_insn "*rev_zero_branch_insn"
+ [(set (pc)
+ (if_then_else (match_operator 1 "eqne_comparison_operator"
+ [(match_operand:SI 2 "register_operand" "r")
+ (const_int 0)])
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ char *br,*invbr;
+ char asmtext[40];
+
+ switch (GET_CODE (operands[1]))
+ {
+ case EQ : br = \"eq\"; invbr = \"ne\"; break;
+ case NE : br = \"ne\"; invbr = \"eq\"; break;
+ case LE : br = \"le\"; invbr = \"gt\"; break;
+ case GT : br = \"gt\"; invbr = \"le\"; break;
+ case LT : br = \"lt\"; invbr = \"ge\"; break;
+ case GE : br = \"ge\"; invbr = \"lt\"; break;
+ }
+
+ /* Is branch target reachable with bxxz? */
+ if (get_attr_length (insn) == 4)
+ {
+ sprintf (asmtext, \"b%sz %%2,%%l0\", invbr);
+ output_asm_insn (asmtext, operands);
+ }
+ else
+ {
+ sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", br);
+ output_asm_insn (asmtext, operands);
+ }
+ return \"\";
+}"
+ [(set_attr "type" "branch")
+ ; We use 25000/50000 instead of 32768/65536 to account for slot filling
+ ; which is complex to track and inaccurate length specs.
+ (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
+ (const_int 25000))
+ (const_int 50000))
+ (const_int 4)
+ (const_int 8)))])
+
+;; Unconditional and other jump instructions.
+
+(define_insn "jump"
+ [(set (pc) (label_ref (match_operand 0 "" "")))]
+ ""
+ "bra %l0"
+ [(set_attr "type" "uncond_branch")
+ (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
+ (const_int 400))
+ (const_int 800))
+ (const_int 2)
+ (const_int 4)))])
+
+(define_insn "indirect_jump"
+ [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
+ ""
+ "jmp %a0"
+ [(set_attr "type" "uncond_branch")
+ (set_attr "length" "2")])
+
+(define_insn "tablejump"
+ [(set (pc) (match_operand:SI 0 "address_operand" "p"))
+ (use (label_ref (match_operand 1 "" "")))]
+ ""
+ "jmp %a0"
+ [(set_attr "type" "uncond_branch")
+ (set_attr "length" "2")])
+
+(define_expand "call"
+ ;; operands[1] is stack_size_rtx
+ ;; operands[2] is next_arg_register
+ [(parallel [(call (match_operand:SI 0 "call_operand" "")
+ (match_operand 1 "" ""))
+ (clobber (reg:SI 14))])]
+ ""
+ "")
+
+(define_insn "*call_via_reg"
+ [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
+ (match_operand 1 "" ""))
+ (clobber (reg:SI 14))]
+ ""
+ "jl %0"
+ [(set_attr "type" "call")
+ (set_attr "length" "2")])
+
+(define_insn "*call_via_label"
+ [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
+ (match_operand 1 "" ""))
+ (clobber (reg:SI 14))]
+ ""
+ "*
+{
+ int call26_p = call26_operand (operands[0], FUNCTION_MODE);
+
+ if (! call26_p)
+ {
+ /* We may not be able to reach with a `bl' insn so punt and leave it to
+ the linker.
+ We do this here, rather than doing a force_reg in the define_expand
+ so these insns won't be separated, say by scheduling, thus simplifying
+ the linker. */
+ return \"seth r14,%T0\;add3 r14,r14,%B0\;jl r14\";
+ }
+ else
+ return \"bl %0\";
+}"
+ [(set_attr "type" "call")
+ (set (attr "length")
+ (if_then_else (eq (symbol_ref "call26_operand (operands[0], FUNCTION_MODE)")
+ (const_int 0))
+ (const_int 12) ; 10 + 2 for nop filler
+ ; The return address must be on a 4 byte boundary so
+ ; there's no point in using a value of 2 here. A 2 byte
+ ; insn may go in the left slot but we currently can't
+ ; use such knowledge.
+ (const_int 4)))])
+
+(define_expand "call_value"
+ ;; operand 2 is stack_size_rtx
+ ;; operand 3 is next_arg_register
+ [(parallel [(set (match_operand 0 "register_operand" "=r")
+ (call (match_operand:SI 1 "call_operand" "")
+ (match_operand 2 "" "")))
+ (clobber (reg:SI 14))])]
+ ""
+ "")
+
+(define_insn "*call_value_via_reg"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand 2 "" "")))
+ (clobber (reg:SI 14))]
+ ""
+ "jl %1"
+ [(set_attr "type" "call")
+ (set_attr "length" "2")])
+
+(define_insn "*call_value_via_label"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
+ (match_operand 2 "" "")))
+ (clobber (reg:SI 14))]
+ ""
+ "*
+{
+ int call26_p = call26_operand (operands[1], FUNCTION_MODE);
+
+ if (! call26_p)
+ {
+ /* We may not be able to reach with a `bl' insn so punt and leave it to
+ the linker.
+ We do this here, rather than doing a force_reg in the define_expand
+ so these insns won't be separated, say by scheduling, thus simplifying
+ the linker. */
+ return \"seth r14,%T1\;add3 r14,r14,%B1\;jl r14\";
+ }
+ else
+ return \"bl %1\";
+}"
+ [(set_attr "type" "call")
+ (set (attr "length")
+ (if_then_else (eq (symbol_ref "call26_operand (operands[1], FUNCTION_MODE)")
+ (const_int 0))
+ (const_int 12) ; 10 + 2 for nop filler
+ ; The return address must be on a 4 byte boundary so
+ ; there's no point in using a value of 2 here. A 2 byte
+ ; insn may go in the left slot but we currently can't
+ ; use such knowledge.
+ (const_int 4)))])
+
+(define_insn "nop"
+ [(const_int 0)]
+ ""
+ "nop"
+ [(set_attr "type" "misc")
+ (set_attr "length" "2")])
+
+;; 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)]
+ ""
+ "")
+
+;; Special pattern to flush the icache.
+
+(define_insn "flush_icache"
+ [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
+ ""
+ "* return \"nop ; flush-icache\";"
+ [(set_attr "type" "misc")])
+
+;; Split up troublesome insns for better scheduling.
+
+;; Peepholes go at the end.
+
+;; ??? Setting the type attribute may not be useful, but for completeness
+;; we do it.
+
+(define_peephole
+ [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
+ (const_int 4)))
+ (match_operand:SI 1 "register_operand" "r"))]
+ "dead_or_set_p (insn, operands[0])"
+ "st %1,@+%0"
+ [(set_attr "type" "store")
+ (set_attr "length" "2")])
diff --git a/gnu/usr.bin/gcc/config/m32r/t-m32r b/gnu/usr.bin/gcc/config/m32r/t-m32r
new file mode 100644
index 00000000000..6005eb96db3
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m32r/t-m32r
@@ -0,0 +1,57 @@
+# lib1funcs.asm is currently empty.
+CROSS_LIBGCC1 =
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so...
+
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+
+# Turn off the SDA while compiling libgcc2. There are no headers for it
+# and we want maximal upward compatibility here.
+
+TARGET_LIBGCC2_CFLAGS = -G 0
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+# We need to use -fpic when we are using gcc to compile the routines in
+# initfini.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 initfini.c.
+# -fpic currently isn't supported for the m32r.
+
+CRTSTUFF_T_CFLAGS =
+
+# .init/.fini section routines
+
+crtinit.o: $(srcdir)/config/m32r/initfini.c $(GCC_PASSES) $(CONFIG_H)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS) \
+ -DCRT_INIT -finhibit-size-directive -fno-inline-functions \
+ -g0 -c $(srcdir)/config/m32r/initfini.c -o crtinit.o
+
+crtfini.o: $(srcdir)/config/m32r/initfini.c $(GCC_PASSES) $(CONFIG_H)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS) \
+ -DCRT_FINI -finhibit-size-directive -fno-inline-functions \
+ -g0 -c $(srcdir)/config/m32r/initfini.c -o crtfini.o
+
+# -mmodel={small,medium} requires separate libraries.
+# We don't build libraries for the large model, instead we use the medium
+# libraries. The only difference is that the large model can handle jumps
+# more than 26 signed bits away.
+
+MULTILIB_OPTIONS = mmodel=small/mmodel=medium
+MULTILIB_DIRNAMES = small medium
+MULTILIB_MATCHES = mmodel?medium=mmodel?large
+
+# Set MULTILIB_EXTRA_OPTS so shipped libraries have small data in .sdata and
+# SHN_M32R_SCOMMON.
+# This is important for objects referenced in system header files.
+MULTILIB_EXTRA_OPTS = msdata=sdata
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
diff --git a/gnu/usr.bin/gcc/config/m32r/xm-m32r.h b/gnu/usr.bin/gcc/config/m32r/xm-m32r.h
new file mode 100644
index 00000000000..57100c875cd
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m32r/xm-m32r.h
@@ -0,0 +1,47 @@
+/* Configuration for GNU C-compiler for the M32R processor.
+ Copyright (C) 1996 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 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
+
+/* Doubles are stored in memory with the high order word first. This
+ matters when cross-compiling. */
+#define HOST_WORDS_BIG_ENDIAN 1
+
+/* target machine dependencies.
+ tm.h is a symbolic link to the actual target specific file. */
+#include "tm.h"
+
+/* Arguments to use with `exit'. */
+#define SUCCESS_EXIT_CODE 0
+#define FATAL_EXIT_CODE 33
+
+/* If compiled with Sun CC, the use of alloca requires this #include. */
+#ifndef __GNUC__
+#include "alloca.h"
+#endif
diff --git a/gnu/usr.bin/gcc/config/m68k/a-ux.h b/gnu/usr.bin/gcc/config/m68k/a-ux.h
new file mode 100644
index 00000000000..74aaa4ea9ad
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/a-ux.h
@@ -0,0 +1,206 @@
+/* Definitions for Motorola 680x0 running A/UX
+ Copyright (C) 1996 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 was renamed from aux.h because of MSDOS: aux.anything
+ isn't usable. Sigh. */
+
+/* Execution environment */
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_BITFIELD|MASK_68881|MASK_68020) /* 68020, 68881 */
+
+#define CPP_PREDEFINES "-Dunix -Dm68k -DAUX -DmacII \
+-Asystem(unix) -Asystem(AUX) -Acpu(m68k) -Amachine(m68k) -Amachine(macII)"
+
+#define CPP_SPEC \
+"%{!msoft-float:%{!ansi:-Dmc68881 }-D__HAVE_68881__ }\
+-Acpu(mc68000) -D__mc68000__ %{!ansi:-Dmc68000 }\
+%{!mc68000:%{!m68000:-Acpu(mc68020) -D__mc68020__ %{!ansi:-Dmc68020 }}}\
+%{m68030:-Acpu(mc68030) -D__mc68030__ %{!ansi:-Dmc68030 }}\
+%{m68040:-Acpu(mc68040) -D__mc68040__ %{!ansi:-Dmc68040 }}\
+%{!ansi:%{!traditional:-D__STDC__=2 }}\
+%{sbsd:-D_BSD_SOURCE -DBSD }%{ZB:-D_BSD_SOURCE -DBSD }\
+%{ssysv:-D_SYSV_SOURCE -DSYSV -DUSG }%{ZS:-D_SYSV_SOURCE -DSYSV -DUSG }\
+%{sposix:-D_POSIX_SOURCE -DPOSIX }%{ZP:-D_POSIX_SOURCE -DPOSIX }\
+%{sposix+:-D_POSIX_SOURCE -DPOSIX }\
+%{saux:-D_AUX_SOURCE }%{ZA:-D_AUX_SOURCE }\
+%{!sbsd:%{!ZB:%{!ssysv:%{!ZS:%{!sposix:%{!ZP:%{!snone:\
+-D_BSD_SOURCE -D_SYSV_SOURCE -D_AUX_SOURCE }}}}}}}"
+
+#define LIB_SPEC \
+"%{sbsd:-lbsd }%{ZB:-lbsd }\
+%{ssysv:-lsvid }%{ZS:-lsvid }\
+%{sposix:-lposix }%{ZP:-lposix }%{sposix+:-lposix }\
+%{!static:%{smac:-lmac_s -lat -lld -lmr }-lc_s }\
+%{static:%{smac:-lmac -lat -lld -lmr }-lc }"
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+"%{pg:mcrt0.o%s }%{!pg:%{p:mcrt1.o%s }\
+%{!p:%{smac:maccrt1.o%s low.o%s }%{!smac:crt1.o%s }}}\
+crt2.o%s "
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtn.o%s "
+
+
+/*===================================================================*/
+/* Compilation environment -- mostly */
+
+#define NO_SYS_SIGLIST
+
+/* We provide atexit(), A/UX does not have it */
+#define HAVE_ATEXIT
+
+/* Generate calls to memcpy, memcmp and memset, as opposed to bcopy, bcmp,
+ and bzero */
+#define TARGET_MEM_FUNCTIONS
+
+/* Resize standard types */
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "int"
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "unsigned int"
+
+/* Every structure or union's size must be a multiple of 2 bytes. */
+#define STRUCTURE_SIZE_BOUNDARY 16
+
+/* Bits needed by collect */
+
+#define OBJECT_FORMAT_COFF
+#define MY_ISCOFF(m) ((m) == M68TVMAGIC || \
+ (m) == M68MAGIC || \
+ (m) == MC68TVMAGIC || \
+ (m) == MC68MAGIC || \
+ (m) == M68NSMAGIC)
+
+
+#ifndef USE_COLLECT2
+/* For .ctor/.dtor sections for collecting constructors */
+/* We have special start/end files for defining [cd]tor lists */
+#define CTOR_LISTS_DEFINED_EXTERNALLY
+#endif
+
+
+/*======================================================================*/
+/* Calling convention and library support changes */
+
+/* Define how to generate (in the callee) the output value of a function
+ and how to find (in the caller) 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.
+ For A/UX generate the result in d0, a0, or fp0 as appropriate. */
+
+#undef FUNCTION_VALUE
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+ (TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_68881 \
+ ? gen_rtx (REG, TYPE_MODE (VALTYPE), 16) \
+ : (TREE_CODE (VALTYPE) == POINTER_TYPE \
+ ? gen_rtx (REG, TYPE_MODE (VALTYPE), 8) \
+ : gen_rtx (REG, TYPE_MODE (VALTYPE), 0)))
+
+#undef LIBCALL_VALUE
+#define LIBCALL_VALUE(MODE) \
+ gen_rtx (REG, (MODE), ((TARGET_68881 && \
+ ((MODE) == SFmode || (MODE) == DFmode)) ? 16 : 0))
+
+/* 1 if N is a possible register number for a function value.
+ For A/UX allow d0, a0, or fp0 as return registers, for integral,
+ pointer, or floating types, respectively. Reject fp0 if not using a
+ 68881 coprocessor. */
+
+#undef FUNCTION_VALUE_REGNO_P
+#define FUNCTION_VALUE_REGNO_P(N) \
+ ((N) == 0 || (N) == 8 || (TARGET_68881 && (N) == 16))
+
+/* Define this to be true when FUNCTION_VALUE_REGNO_P is true for
+ more than one register. */
+
+#undef NEEDS_UNTYPED_CALL
+#define NEEDS_UNTYPED_CALL 1
+
+/* For compatibility with the large body of existing code which does not
+ always properly declare external functions returning pointer types, the
+ A/UX convention is to copy the value returned for pointer functions
+ from a0 to d0 in the function epilogue, so that callers that have
+ neglected to properly declare the callee can still find the correct return
+ value. */
+
+#define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \
+{ \
+ extern int current_function_returns_pointer; \
+ if ((current_function_returns_pointer) && \
+ ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
+ asm_fprintf (FILE, "\t%s %Ra0,%Rd0\n", ASM_MOV_INSN); \
+}
+
+/* How to call the function profiler */
+
+#undef FUNCTION_PROFILER
+#define FUNCTION_PROFILER(FILE, LABELNO) \
+ asm_fprintf (FILE, "\t%Olea %LLP%d,%Ra0\n\t%Ojbsr %s\n", \
+ (LABELNO), FUNCTION_PROFILER_SYMBOL)
+
+/* Finalize the trampoline by flushing the insn cache */
+
+#undef FINALIZE_TRAMPOLINE
+#define FINALIZE_TRAMPOLINE(TRAMP) \
+ emit_library_call(gen_rtx(SYMBOL_REF, Pmode, "__clear_cache"), \
+ 0, VOIDmode, 2, TRAMP, Pmode, \
+ plus_constant(TRAMP, TRAMPOLINE_SIZE), Pmode);
+
+/* Clear the instruction cache from `beg' to `end'. This makes an
+ inline system call to SYS_sysm68k. The arguments are as follows:
+
+ sysm68k(105, addr, scope, cache, len)
+
+ 105 - the subfunction code to clear the cache
+ addr - the start address for the flush
+ scope - the scope of the flush (see the cpush insn)
+ cache - which cache to flush (see the cpush insn)
+ len - a factor relating to the number of flushes to perform :
+ len/16 lines, or len/4096 pages.
+
+ While all this is only really relevant to 040's, the system call
+ will just return an error (which we ignore) on other systems. */
+
+#define CLEAR_INSN_CACHE(beg, end) \
+{ \
+ unsigned _beg = (unsigned)(beg), _end = (unsigned)(end); \
+ unsigned _len = ((_end / 16) - (_beg / 16) + 1) * 16; \
+ __asm __volatile( \
+ ASM_MOV_INSN " %1, %-\n\t" /* nr lines */ \
+ ASM_MOV_INSN " %#3, %-\n\t" /* insn+data caches */ \
+ ASM_MOV_INSN " %#1, %-\n\t" /* clear lines */ \
+ ASM_MOV_INSN " %0, %-\n\t" /* beginning of buffer */ \
+ ASM_MOV_INSN " %#105, %-\n\t" /* cache sub-function nr */ \
+ ASM_MOV_INSN " %#0, %-\n\t" /* dummy return address */ \
+ ASM_MOV_INSN " %#38, %/d0\n\t" /* system call nr */ \
+ "trap %#0\n\t" \
+ "add%.l %#24, %/sp" \
+ : /* no outputs */ \
+ : "g"(_beg), "g"(_len) \
+ : "%d0"); \
+}
diff --git a/gnu/usr.bin/gcc/config/m68k/aux-crt1.c b/gnu/usr.bin/gcc/config/m68k/aux-crt1.c
new file mode 100644
index 00000000000..9ee529b053d
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/aux-crt1.c
@@ -0,0 +1,134 @@
+/* Startup code for A/UX
+ Copyright (C) 1996 Free Software Foundation, Inc.
+
+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 is compiled three times to produce crt1.o, mcrt1.o, and
+ maccrt1.o. The final two are created by defining MCRT1 and MACCRT1
+ respectively. */
+
+#include <stdlib.h>
+#ifdef MCRT1
+#include <unistd.h>
+#include <mon.h>
+#endif
+
+/* Extern function declarations */
+
+extern void initfpu(void);
+extern void __istart(void);
+extern void __compatmode(void);
+extern void _cleanup(void);
+extern int main(int, char **, char **);
+extern void exit(int) __attribute__((noreturn));
+extern void _exit(int) __attribute__((noreturn));
+
+#ifdef MACCRT1
+extern void InitMac(void);
+#endif
+#ifdef MCRT1
+static void monitor_start(void);
+#endif
+
+/* Global variables */
+
+char **environ;
+char *__splimit; /* address of top of stack */
+
+
+/* Initialize system and run */
+
+void _start() __attribute__((noreturn));
+void _start()
+{
+ register int *fp __asm__("%a6");
+ register char *d0 __asm__("%d0");
+ char **argv;
+ int argc;
+
+ __splimit = d0;
+ argc = fp[1];
+ argv = (char **)&fp[2];
+ environ = &argv[argc+1];
+
+ initfpu();
+ __istart();
+ __compatmode();
+
+ atexit(_cleanup);
+#ifdef MCRT1
+ monitor_start();
+#endif
+#ifdef MACCRT1
+ InitMac();
+#endif
+
+ exit(main(argc, argv, environ));
+}
+
+
+#ifdef MCRT1
+/* Start/Stop program monitor */
+
+extern void monitor(void *, void *, WORD *, int, int);
+
+static WORD *monitor_buffer;
+
+static void monitor_cleanup(void)
+{
+ monitor(NULL, NULL, NULL, 0, 0);
+ free(monitor_buffer);
+}
+
+static void monitor_start(void)
+{
+ extern int etext;
+ extern int stext __asm__(".text");
+
+ /* Choice of buffer size should be "no more than a few times
+ smaller than the program size" -- I don't believe that there
+ are any (useful) functions smaller than two insns (4 bytes)
+ so that is the scale factor used here */
+ int len = (&etext - &stext + 1) / 4;
+
+ monitor_buffer = (WORD *)calloc(len, sizeof(WORD));
+ if (monitor_buffer == NULL)
+ {
+ static const char msg[] = "mcrt1: could not allocate monitor buffer\n";
+ write(2, msg, sizeof(msg)-1);
+ _exit(-1);
+ }
+
+ /* I'm not sure why the count cap at 600 -- but that is what A/UX does */
+ monitor(&stext, &etext, monitor_buffer, len, 600);
+
+ atexit(monitor_cleanup);
+}
+#endif /* MCRT1 */
diff --git a/gnu/usr.bin/gcc/config/m68k/aux-crt2.asm b/gnu/usr.bin/gcc/config/m68k/aux-crt2.asm
new file mode 100644
index 00000000000..062c16ae8c2
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/aux-crt2.asm
@@ -0,0 +1,42 @@
+/* More startup code for A/UX */
+
+#include "tm.h"
+
+#ifdef USE_BIN_AS
+ file "crt2.s"
+
+/* The init section is used to support shared libraries */
+ init
+ global __istart
+
+__istart:
+ link %fp,&-4
+#else
+ .file "crt2.s"
+
+/* The init section is used to support shared libraries */
+.section .init, "x"
+.even
+.globl __istart
+
+__istart:
+ link %fp,#-4
+
+#ifndef USE_COLLECT2
+/* The ctors and dtors sections are used to support COFF collection of
+ c++ constructors and destructors */
+.section .ctors, "d"
+.even
+.globl __CTOR_LIST__
+
+__CTOR_LIST__:
+ .long -1
+
+.section .dtors, "d"
+.even
+.globl __DTOR_LIST__
+
+__DTOR_LIST__:
+ .long -1
+#endif /* USE_COLLECT2 */
+#endif /* USE_BIN_AS */
diff --git a/gnu/usr.bin/gcc/config/m68k/aux-crtn.asm b/gnu/usr.bin/gcc/config/m68k/aux-crtn.asm
new file mode 100644
index 00000000000..ce63d7fead7
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/aux-crtn.asm
@@ -0,0 +1,26 @@
+/* More startup code for A/UX */
+
+#include "tm.h"
+
+#ifdef USE_BIN_AS
+ file "crtn.s"
+
+ init
+
+ unlk %fp
+ rts
+#else
+ .file "crtn.s"
+
+.section .init, "x"
+ unlk %fp
+ rts
+
+#ifndef USE_COLLECT2
+.section .ctors, "d"
+ .long 0
+
+.section .dtors, "d"
+ .long 0
+#endif /* USE_COLLECT2 */
+#endif /* USE_BIN_AS */
diff --git a/gnu/usr.bin/gcc/config/m68k/aux-exit.c b/gnu/usr.bin/gcc/config/m68k/aux-exit.c
new file mode 100644
index 00000000000..fe06c77c406
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/aux-exit.c
@@ -0,0 +1,99 @@
+/* Generic atexit()
+ Copyright (C) 1996 Free Software Foundation, Inc.
+
+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. */
+
+/* Rather than come up with some ugly hack to make mcrt1 work, it is
+ better to just go ahead and provide atexit(). */
+
+
+#include <stdlib.h>
+
+
+void exit(int) __attribute__((noreturn));
+void _exit(int) __attribute__((noreturn));
+void _cleanup(void);
+
+
+#define FNS_PER_BLOCK 32
+
+struct atexit_fn_block
+{
+ struct atexit_fn_block *next;
+ void (*fns[FNS_PER_BLOCK])(void);
+ short used;
+};
+
+
+/* staticly allocate the first block */
+static struct atexit_fn_block atexit_fns;
+static struct atexit_fn_block *current_block = &atexit_fns;
+
+
+int atexit(void (*fn)(void))
+{
+ if (current_block->used >= FNS_PER_BLOCK)
+ {
+ struct atexit_fn_block *new_block =
+ (struct atexit_fn_block *)malloc(sizeof(struct atexit_fn_block));
+ if (new_block == NULL)
+ return -1;
+
+ new_block->used = 0;
+ new_block->next = current_block;
+ current_block = new_block;
+ }
+
+ current_block->fns[current_block->used++] = fn;
+
+ return 0;
+}
+
+
+void exit(int status)
+{
+ struct atexit_fn_block *block = current_block, *old_block;
+ short i;
+
+ while (1)
+ {
+ for (i = block->used; --i >= 0 ;)
+ (*block->fns[i])();
+ if (block == &atexit_fns)
+ break;
+ /* I know what you are thinking -- we are about to exit, why free?
+ Because it is friendly to memory leak detectors, that's why. */
+ old_block = block;
+ block = block->next;
+ free(old_block);
+ }
+
+ _exit(status);
+}
diff --git a/gnu/usr.bin/gcc/config/m68k/aux-low.gld b/gnu/usr.bin/gcc/config/m68k/aux-low.gld
new file mode 100644
index 00000000000..d1bb2a99080
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/aux-low.gld
@@ -0,0 +1,38 @@
+/* GLD link script for building mac-compatible executables */
+
+OUTPUT_FORMAT("coff-m68k")
+
+SEARCH_DIR(@tooldir@/lib);
+SEARCH_DIR(@libdir@);
+SEARCH_DIR(/lib);
+SEARCH_DIR(/usr/lib);
+SEARCH_DIR(@local_prefix@/lib);
+
+ENTRY(_start)
+
+SECTIONS
+{
+ .lowmem 0 (DSECT) : {
+ /usr/lib/low.o (.data)
+ }
+ .text 0x10000000 : {
+ *(.text)
+ *(.init)
+ *(.fini)
+ etext = .;
+ _etext = .;
+ }
+ .data ALIGN(0x40000) : {
+ *(.data)
+ *(.ctors)
+ *(.dtors)
+ edata = .;
+ _edata = .;
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ end = .;
+ _end = .;
+ }
+}
diff --git a/gnu/usr.bin/gcc/config/m68k/aux-mcount.c b/gnu/usr.bin/gcc/config/m68k/aux-mcount.c
new file mode 100644
index 00000000000..1001c84762b
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/aux-mcount.c
@@ -0,0 +1,69 @@
+/* Profiling support code for A/UX
+ Copyright (C) 1996 Free Software Foundation, Inc.
+
+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 routine is called at the beginning of functions compiled with -p
+ or -pg. The A/UX libraries call mcount%, but gas cannot generate
+ symbols with embedded percent signs. Previous ports of GCC to A/UX
+ have done things like (1) assemble a stub routine with the native
+ assembler, or (2) assemble a stub routine with gas and edit the object
+ file. This solution has the advantage that it can interoperate with
+ the A/UX version and can be used in an eventual port of glibc to A/UX. */
+
+#ifndef __GNUC__
+#error This file uses GNU C extensions
+#endif
+
+#include <mon.h>
+
+#ifdef IN_GCC
+#include "tm.h"
+#endif
+
+struct cnt *_countbase;
+
+#ifdef FUNCTION_PROFILER_SYMBOL
+void __mcount() __asm__(FUNCTION_PROFILER_SYMBOL);
+#endif
+
+void __mcount()
+{
+ register long **pfncnt __asm__("%a0");
+ register long *fncnt = *pfncnt;
+
+ if (!fncnt)
+ {
+ struct cnt *newcnt = _countbase++;
+ newcnt->fnpc = (char *)__builtin_return_address(0);
+ *pfncnt = fncnt = &newcnt->mcnt;
+ }
+ *fncnt += 1;
+}
diff --git a/gnu/usr.bin/gcc/config/m68k/auxas.h b/gnu/usr.bin/gcc/config/m68k/auxas.h
new file mode 100644
index 00000000000..794df51558f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/auxas.h
@@ -0,0 +1,189 @@
+/* Definitions for Motorola 680x0 running A/UX using /bin/as
+ Copyright (C) 1996, 1997 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 USE_BIN_AS
+
+#ifndef USE_COLLECT2
+#define USE_COLLECT2
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include "m68k/sgs.h"
+
+#define ASM_SPEC "%{m68030:-68030 }%{m68040:-68040 }"
+
+/* Modify AT&T SGS assembler syntax */
+/* A/UX's as doesn't do dots in pseudo-ops */
+
+#define SDB_DEBUGGING_INFO
+
+#define NO_DOLLAR_IN_LABEL
+#define NO_DOT_IN_LABEL
+
+#undef TEXT_SECTION_ASM_OP
+#define TEXT_SECTION_ASM_OP "\ttext"
+
+#undef DATA_SECTION_ASM_OP
+#define DATA_SECTION_ASM_OP "\tdata\t1"
+
+#undef BYTE_ASM_OP
+#define BYTE_ASM_OP "byte"
+
+#undef WORD_ASM_OP
+#define WORD_ASM_OP "short"
+
+#undef LONG_ASM_OP
+#define LONG_ASM_OP "long"
+
+#undef SPACE_ASM_OP
+#define SPACE_ASM_OP "space"
+
+#undef ALIGN_ASM_OP
+#define ALIGN_ASM_OP "align"
+
+#undef GLOBAL_ASM_OP
+#define GLOBAL_ASM_OP "\tglobal"
+
+#undef SWBEG_ASM_OP
+#define SWBEG_ASM_OP "swbeg"
+
+#undef SET_ASM_OP
+#define SET_ASM_OP "set"
+
+#undef ASM_PN_FORMAT
+#define ASM_PN_FORMAT "%s%%%d"
+
+#undef LOCAL_LABEL_PREFIX
+#define LOCAL_LABEL_PREFIX "L%"
+
+#define ADDITIONAL_REGISTER_NAMES { "%a6", 14, "%a7", 15 }
+
+#undef ASM_OUTPUT_INT
+#define ASM_OUTPUT_INT(FILE,VALUE) \
+( fprintf ((FILE), "\t%s ", LONG_ASM_OP), \
+ output_addr_const ((FILE), (VALUE)), \
+ fprintf ((FILE), "\n"))
+
+#undef ASM_OUTPUT_COMMON
+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
+( fputs ("\tcomm\t", (FILE)), \
+ assemble_name ((FILE), (NAME)), \
+ fprintf ((FILE), ",%u\n", (ROUNDED)))
+
+#undef ASM_OUTPUT_LOCAL
+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
+( fputs ("\tlcomm\t", (FILE)), \
+ assemble_name ((FILE), (NAME)), \
+ fprintf ((FILE), ",%u\n", (ROUNDED)))
+
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) \
+ output_file_directive ((FILE), main_input_filename)
+
+#undef ASM_OUTPUT_SOURCE_FILENAME
+#define ASM_OUTPUT_SOURCE_FILENAME(FILE, NAME) \
+( fputs ("\tfile\t", (FILE)), \
+ output_quoted_string ((FILE), (NAME)), \
+ fputc ('\n', (FILE)) )
+
+#undef ASM_OUTPUT_CASE_FETCH
+#define ASM_OUTPUT_CASE_FETCH(file, labelno, regname) \
+ asm_fprintf (file, "10(%Rpc,%s.", regname)
+
+#define SGS_NO_LI
+
+/* Random macros describing parts of SDB data. */
+
+#define PUT_SDB_SCL(a) \
+ fprintf(asm_out_file, "\tscl\t%d%s", (a), SDB_DELIM)
+
+#define PUT_SDB_INT_VAL(a) \
+ fprintf (asm_out_file, "\tval\t%d%s", (a), SDB_DELIM)
+
+#define PUT_SDB_VAL(a) \
+( fputs ("\tval\t", asm_out_file), \
+ output_addr_const (asm_out_file, (a)), \
+ fprintf (asm_out_file, SDB_DELIM))
+
+#define PUT_SDB_DEF(a) \
+do { fprintf (asm_out_file, "\tdef\t"); \
+ ASM_OUTPUT_LABELREF (asm_out_file, a); \
+ fprintf (asm_out_file, SDB_DELIM); } while (0)
+
+#define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\tdef\t~%s%s", a, SDB_DELIM)
+
+#define PUT_SDB_ENDEF fputs("\tendef\n", asm_out_file)
+
+#define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\ttype\t0%o%s", a, SDB_DELIM)
+
+#define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\tsize\t%d%s", a, SDB_DELIM)
+
+#define PUT_SDB_START_DIM fprintf(asm_out_file, "\tdim\t")
+
+#define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a)
+
+#define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d%s", a, SDB_DELIM)
+
+#define PUT_SDB_TAG(a) \
+do { fprintf (asm_out_file, "\ttag\t"); \
+ ASM_OUTPUT_LABELREF (asm_out_file, a); \
+ fprintf (asm_out_file, SDB_DELIM); } while (0)
+
+#define PUT_SDB_BLOCK_START(LINE) \
+ fprintf (asm_out_file, \
+ "\tdef\t~bb%s\tval\t~%s\tscl\t100%s\tline\t%d%s\tendef\n", \
+ SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
+
+#define PUT_SDB_BLOCK_END(LINE) \
+ fprintf (asm_out_file, \
+ "\tdef\t~eb%s\tval\t~%s\tscl\t100%s\tline\t%d%s\tendef\n", \
+ SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
+
+#define PUT_SDB_FUNCTION_START(LINE) \
+ fprintf (asm_out_file, \
+ "\tdef\t~bf%s\tval\t~%s\tscl\t101%s\tline\t%d%s\tendef\n", \
+ SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
+
+#define PUT_SDB_FUNCTION_END(LINE) \
+ fprintf (asm_out_file, \
+ "\tdef\t~ef%s\tval\t~%s\tscl\t101%s\tline\t%d%s\tendef\n", \
+ SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
+
+#define PUT_SDB_EPILOGUE_END(NAME) \
+do { fprintf (asm_out_file, "\tdef\t"); \
+ ASM_OUTPUT_LABELREF (asm_out_file, NAME); \
+ fprintf (asm_out_file, \
+ "%s\tval\t~%s\tscl\t-1%s\tendef\n", \
+ SDB_DELIM, SDB_DELIM, SDB_DELIM); } while (0)
+
+#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
+ sprintf ((BUFFER), "~%dfake", (NUMBER));
+
+#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \
+ fprintf((FILE), "\tln\t%d\n", \
+ (sdb_begin_function_line > 1 ? \
+ last_linenum - sdb_begin_function_line : 1))
+
+#define ASM_MOV_INSN "mov.l"
+
+#define FUNCTION_PROFILER_SYMBOL "mcount%"
+
+#endif /* !__ASSEMBLY__ */
diff --git a/gnu/usr.bin/gcc/config/m68k/auxgas.h b/gnu/usr.bin/gcc/config/m68k/auxgas.h
new file mode 100644
index 00000000000..c2e0d567b45
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/auxgas.h
@@ -0,0 +1,56 @@
+/* Definitions for Motorola 680x0 running A/UX using GAS
+ Copyright (C) 1996 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 USE_GAS
+
+#ifndef __ASSEMBLY__
+
+#include "m68k/m68k.h"
+#include "m68k/coff.h"
+
+#define ASM_SPEC "%{m68000:-Am68000 }%{m68030:-Am68030 }%{m68040:-Am68040 }"
+
+/* Output #ident as a .ident. */
+#define ASM_OUTPUT_IDENT(FILE, NAME) \
+ fprintf (FILE, "\t.ident \"%s\"\n", NAME);
+
+#ifdef IDENTIFY_WITH_IDENT
+/* Put the GCC identification somewhere nicer, I think.
+ Does the COFF GDB use the "gcc2_complied." symbol anyway? */
+#define ASM_IDENTIFY_GCC(FILE) /* nothing */
+#define ASM_IDENTIFY_LANGUAGE(FILE) \
+ fprintf (FILE, "\t.ident \"GCC (%s) %s\"\n", lang_identify(), version_string)
+#endif
+
+#ifdef USE_COLLECT2
+#undef ASM_OUTPUT_CONSTRUCTOR
+#undef ASM_OUTPUT_DESTRUCTOR
+/* for the sake of link-level compatibility with /bin/as version */
+#define NO_DOLLAR_IN_LABEL
+#define NO_DOT_IN_LABEL
+#endif
+
+#define ADDITIONAL_REGISTER_NAMES { "%fp", 14, "%a7", 15 }
+
+#define ASM_MOV_INSN "movel"
+
+#define FUNCTION_PROFILER_SYMBOL "__mcount"
+
+#endif /* !__ASSEMBLY__ */
diff --git a/gnu/usr.bin/gcc/config/m68k/auxgld.h b/gnu/usr.bin/gcc/config/m68k/auxgld.h
new file mode 100644
index 00000000000..12c97afaead
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/auxgld.h
@@ -0,0 +1,29 @@
+/* Definitions for Motorola 680x0 running A/UX using GLD
+ Copyright (C) 1996 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 USE_GNU_LD
+
+#ifndef __ASSEMBLY__
+
+#define LINK_SPEC \
+"%{p:-L/lib/libp -L/usr/lib/libp }%{pg:-L/lib/libp -L/usr/lib/libp }\
+%{smac:-T low.gld%s }"
+
+#endif /* !__ASSEMBLY__ */
diff --git a/gnu/usr.bin/gcc/config/m68k/auxld.h b/gnu/usr.bin/gcc/config/m68k/auxld.h
new file mode 100644
index 00000000000..932dd6ab953
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/auxld.h
@@ -0,0 +1,35 @@
+/* Definitions for Motorola 680x0 running A/UX using /bin/ld
+ Copyright (C) 1996 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 USE_BIN_LD
+
+#ifndef USE_COLLECT2
+#define USE_COLLECT2
+#endif
+
+#ifndef __ASSEMBLY__
+
+#define LINK_SPEC \
+"%{p:-L/lib/libp -L/usr/lib/libp }%{pg:-L/lib/libp -L/usr/lib/libp }\
+%{smac:low.ld%s }%{!smac:shlib.ld%s }"
+
+#define SWITCHES_NEED_SPACES "o"
+
+#endif /* !__ASSEMBLY__ */
diff --git a/gnu/usr.bin/gcc/config/m68k/m68k-psos.h b/gnu/usr.bin/gcc/config/m68k/m68k-psos.h
new file mode 100644
index 00000000000..8e5b843397e
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/m68k-psos.h
@@ -0,0 +1,67 @@
+/* Definitions of a target machine for the GNU compiler:
+ 68040 running pSOS, ELF object files, DBX debugging.
+ Copyright (C) 1996 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. */
+
+
+/* Use MOTOROLA assembler syntax, as gas is configured that way and
+ glibc also seems to use it. Must come BEFORE m68k.h! */
+
+#define MOTOROLA
+
+/* Get generic m68k definitions. */
+
+#include "m68k/m68k.h"
+#include "m68k/m68kemb.h"
+
+/* Default processor type is a (pure) 68040 with 68881 emulation using
+ the floating-point support package. */
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_68040_ONLY|MASK_BITFIELD|MASK_68881|MASK_68020)
+
+/* Options passed to CPP, GAS, CC1 and CC1PLUS. We override
+ m68k-none.h for consistency with TARGET_DEFAULT. */
+
+#undef CPP_SPEC
+#define CPP_SPEC \
+"%{!mc68000:%{!m68000:%{!m68332:%{!msoft-float:-D__HAVE_68881__ }}}}\
+%{!ansi:-Dmc68000 %{m68010:-Dmc68010 }%{m68020:-Dmc68020 }%{mc68020:-Dmc68020 }%{m68030:-Dmc68030 }%{m68040:-Dmc68040 }%{m68020-40:-Dmc68020 -Dmc68030 -Dmc68040 }%{m68302:-Dmc68302 }%{m68332:-Dmc68332 }%{!mc68000:%{!m68000:%{!m68010:%{!mc68020:%{!m68020:%{!m68030:%{!m68040:%{!m68020-40:%{!m68302:%{!m68332:-Dmc68040 }}}}}}}}}}}\
+-D__mc68000__ -D__mc68000 %{m68010:-D__mc68010__ -D__mc68010 }%{m68020:-D__mc68020__ -D__mc68020 }%{mc68020:-D__mc68020__ -D__mc68020 }%{m68030:-D__mc68030__ -D__mc68030 }%{m68040:-D__mc68040__ -D__mc68040 }%{m68020-40:-D__mc68020__ -D__mc68030__ -D__mc68040__ -D__mc68020 -D__mc68030 -D__mc68040 }%{m68302:-D__mc68302__ -D__mc68302 }%{m68332:-D__mc68332__ -D__mc68332 }%{!mc68000:%{!m68000:%{!m68010:%{!mc68020:%{!m68020:%{!m68030:%{!m68040:%{!m68020-40:%{!m68302:%{!m68332:-D__mc68040__ -D__mc68040 }}}}}}}}}}"
+
+#undef ASM_SPEC
+#define ASM_SPEC \
+"%{m68851}%{mno-68851}%{m68881}%{mno-68881}%{msoft-float:-mno-68881 }\
+%{m68000}%{mc68000}%{m68010}%{m68020}%{mc68020}%{m68030}%{m68040}%{m68020-40:-mc68040}%{m68302}%{m68332}%{!m68000:%{!mc68000:%{!m68010:%{!mc68020:%{!m68020:%{!m68030:%{!m68040:%{!m68020-40:%{!m68302:%{!m68332:-mc68040}}}}}}}}}}"
+
+#undef CC1_SPEC
+#define CC1_SPEC \
+ "%{m68000:%{!m68881:-msoft-float }}%{m68302:-m68000}%{m68332:-m68020 -mnobitfield %{!m68881:-msoft-float}}%{!m68000:%{!mc68000:%{!m68010:%{!mc68020:%{!m68020:%{!m68030:%{!m68040:%{!m68020-40:%{!m68302:%{!m68332:-m68040}}}}}}}}}}"
+
+#undef CC1PLUS_SPEC
+#define CC1PLUS_SPEC \
+ "%{m68000:%{!m68881:-msoft-float }}%{m68302:-m68000}%{m68332:-m68020 -mnobitfield %{!m68881:-msoft-float}}%{!m68000:%{!mc68000:%{!m68010:%{!mc68020:%{!m68020:%{!m68030:%{!m68040:%{!m68020-40:%{!m68302:%{!m68332:-m68040}}}}}}}}}}"
+
+
+/* Get processor-independent pSOS definitions. */
+
+#include "psos.h"
+
+
+/* end of m68k-psos.h */
diff --git a/gnu/usr.bin/gcc/config/m68k/mot3300-crt0.S b/gnu/usr.bin/gcc/config/m68k/mot3300-crt0.S
new file mode 100644
index 00000000000..2a84b37716c
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/mot3300-crt0.S
@@ -0,0 +1,98 @@
+/* The start module crt0.s for the SysV68 Motorola 3300 Delta Series.
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ Contributed by Manfred Hollstein (manfred@lts.sel.alcatel.de).
+
+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. */
+
+#ifdef MOTOROLA
+# define COMM comm
+# define DATA data
+# define EVEN even
+# define FILE(n) file n
+# define GLOBAL_SYM(s) global s
+# define LOCAL_LABEL(l) L%##l
+# define IDENT(s) ident s
+# define TEXT text
+#else /* Assume we are using GNU as. */
+# define COMM .comm
+# define DATA .data
+# define EVEN .even
+# define FILE(name) .file name
+# define GLOBAL_SYM(s) .globl s
+# define LOCAL_LABEL(l) .L.##l
+# define IDENT(s) .section .comment;.asciz s
+# define TEXT .text
+#endif
+
+ FILE ("crt0.s")
+ TEXT
+ GLOBAL_SYM (_start)
+_start: mov.l %d0,splimit%
+ subq.w &8,%sp
+ mov.l 8(%sp),(%sp)
+ lea 12(%sp),%a0
+ mov.l %a0,4(%sp)
+ mov.l %a0,%a1
+LOCAL_LABEL(0):
+ tst.l (%a0)+
+ bne.b LOCAL_LABEL(0)
+#ifdef SGS_CMP_ORDER
+ cmpa.l %a0,(%a1)
+#else
+ cmpa.l (%a1),%a0
+#endif
+ blt.b LOCAL_LABEL(1)
+ subq.w &4,%a0
+LOCAL_LABEL(1):
+ mov.l %a0,8(%sp)
+ mov.l %a0,environ
+ jsr initfpu
+
+ subq.w &8,%sp
+ clr.l %d0 /* if (! isatty (fileno (stderr))) */
+ mov.b _iob+27,%d0
+ mov.l %d0,-(%sp)
+ jsr isatty
+ addq.w &4,%sp
+ tst.l %d0
+ bne.b LOCAL_LABEL(isatty)
+ clr.l -(%sp) /* setbuf (stderr, NULL) */
+ pea _iob+28
+ jsr setbuf
+ addq.w &8,%sp
+LOCAL_LABEL(isatty):
+ addq.w &8,%sp
+
+ jsr main
+ mov.l %d0,(%sp)
+ jsr exit
+ moveq.l &1,%d0
+ trap &0
+ nop
+
+ GLOBAL_SYM (__stop_monitor)
+__stop_monitor:
+ rts
+ EVEN
+
+ COMM splimit%,4
+ COMM environ,4
+
+ IDENT ("$Id: mot3300-crt0.S,v 1.1 1998/02/14 19:18:52 niklas Exp $")
+ IDENT ("Contributed by Manfred Hollstein (manfred@lts.sel.alcatel.de)")
+ IDENT ("Corrections by Philippe De Muyter (phdm@macqel.be)")
diff --git a/gnu/usr.bin/gcc/config/m68k/mot3300Mcrt0.S b/gnu/usr.bin/gcc/config/m68k/mot3300Mcrt0.S
new file mode 100644
index 00000000000..271c81c725a
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/mot3300Mcrt0.S
@@ -0,0 +1,142 @@
+/* The start module mcrt0.s for the SysV68 Motorola 3300 Delta Series.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Manfred Hollstein (manfred@lts.sel.alcatel.de).
+
+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. */
+
+#ifdef MOTOROLA
+# define COMM comm
+# define DATA data
+# define EVEN even
+# define FILE(n) file n
+# define GLOBAL_SYM(s) global s
+# define LOCAL_LABEL(l) L%##l
+# define IDENT(s) ident s
+# define TEXT text
+#else /* Assume we are using GNU as. */
+# define COMM .comm
+# define DATA .data
+# define EVEN .even
+# define FILE(name) .file name
+# define GLOBAL_SYM(s) .globl s
+# define LOCAL_LABEL(l) .L.##l
+# define IDENT(s) .section .comment;.asciz s
+# define TEXT .text
+#endif
+
+ FILE ("mcrt0.s")
+ TEXT
+ GLOBAL_SYM (_start)
+_start: mov.l %d0,splimit%
+ subq.w &8,%sp
+ mov.l 8(%sp),(%sp)
+ lea 12(%sp),%a0
+ mov.l %a0,___Argv
+ mov.l %a0,4(%sp)
+ mov.l %a0,%a1
+LOCAL_LABEL(0):
+ tst.l (%a0)+
+ bne.b LOCAL_LABEL(0)
+#ifdef SGS_CMP_ORDER
+ cmpa.l %a0,(%a1)
+#else
+ cmpa.l (%a1),%a0
+#endif
+ blt.b LOCAL_LABEL(1)
+ subq.w &4,%a0
+LOCAL_LABEL(1):
+ mov.l %a0,8(%sp)
+ mov.l %a0,environ
+ jsr initfpu
+
+ sub &8,%sp
+ clr.l %d0 /* if (! isatty (fileno (stderr))) */
+ mov.b _iob+27,%d0
+ mov.l %d0,-(%sp)
+ jsr isatty
+ addq.w &4,%sp
+ tst.l %d0
+ bne.b LOCAL_LABEL(isatty)
+ clr.l -(%sp) /* setbuf (stderr, NULL) */
+ pea _iob+28
+ jsr setbuf
+ addq.w &8,%sp
+LOCAL_LABEL(isatty):
+ addq.w &8,%sp
+
+ mov.l &600,-(%sp)
+ mov.l &etext,%d1
+ subi.l &LOCAL_LABEL(endofstart),%d1
+ addq.l &1,%d1
+ bclr &0,%d1
+ addi.l &4812,%d1
+ asr.l &1,%d1
+ mov.l %d1,-(%sp)
+ add.l %d1,%d1
+ mov.l %d1,-(%sp)
+ jsr sbrk
+ addq.w &4,%sp
+#ifdef SGS_CMP_ORDER
+ cmpa.l %a0,&-1
+#else
+ cmpa.l &-1,%a0
+#endif
+ beq.b LOCAL_LABEL(3)
+ mov.l %a0,-(%sp)
+ add.l &12,%a0
+ mov.l %a0,_countbase
+ mov.l &etext,-(%sp)
+ mov.l &LOCAL_LABEL(endofstart),-(%sp)
+ jsr monitor
+ lea 20(%sp),%sp
+ jsr main
+ mov.l %d0,(%sp)
+ jsr exit
+_exit: moveq &1,%d0
+ trap &0
+
+ GLOBAL_SYM (__stop_monitor)
+__stop_monitor:
+ clr.l -(%sp)
+ jsr monitor
+ add.w &4,%sp
+ rts
+
+LOCAL_LABEL(errtxt):
+ byte 'N,'o,' ,'s,'p,'a,'c,'e,' ,'f,'o,'r,' ,'m,'o,'n
+ byte 'i,'t,'o,'r,' ,'b,'u,'f,'f,'e,'r,'\n
+LOCAL_LABEL(errtxt_end):
+
+ EVEN
+LOCAL_LABEL(3):
+ pea LOCAL_LABEL(errtxt_end)-LOCAL_LABEL(errtxt)
+ pea LOCAL_LABEL(errtxt)(%pc)
+ pea 2
+ jsr write
+ bra.b _exit
+LOCAL_LABEL(endofstart):
+
+ EVEN
+
+ COMM splimit%,4
+ COMM environ,4
+ COMM _countbase,4
+
+ IDENT ("$Id: mot3300Mcrt0.S,v 1.1 1998/02/14 19:18:55 niklas Exp $")
+ IDENT ("Contributed by Manfred Hollstein (manfred@lts.sel.alcatel.de)")
+ IDENT ("Corrections by Philippe De Muyter (phdm@macqel.be)")
diff --git a/gnu/usr.bin/gcc/config/m68k/rtems.h b/gnu/usr.bin/gcc/config/m68k/rtems.h
new file mode 100644
index 00000000000..77c02f8e9c8
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/rtems.h
@@ -0,0 +1,28 @@
+/* Definitions for rtems targeting a Motorola m68k using coff.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Joel Sherrill (joel@OARcorp.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 "m68k/m68k-coff.h"
+
+/* Specify predefined symbols in preprocessor. */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Dmc68000 -Drtems -D__rtems__ \
+ -Asystem(rtems) -Acpu(mc68000) -Acpu(m68k) -Amachine(m68k)"
diff --git a/gnu/usr.bin/gcc/config/m68k/t-aux b/gnu/usr.bin/gcc/config/m68k/t-aux
new file mode 100644
index 00000000000..3d59d675ffd
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/t-aux
@@ -0,0 +1,44 @@
+# Makefile additions for A/UX
+
+LIB2FUNCS_EXTRA=aux-mcount.c aux-exit.c
+
+FIXPROTO_DEFINES=-D_POSIX_SOURCE
+
+# Only really needed for collect2
+CLIB=-lld
+
+# Needed to support builds for multiple versions of A/UX
+# LDFLAGS=-static
+
+# Make sure we get the right assembler by letting gcc choose
+AS = $(GCC_FOR_TARGET) -xassembler-with-cpp -D__ASSEMBLY__ $(INCLUDES) -c
+
+aux-mcount.c: $(srcdir)/config/m68k/aux-mcount.c
+ cp $(srcdir)/config/m68k/aux-mcount.c aux-mcount.c
+
+aux-exit.c: $(srcdir)/config/m68k/aux-exit.c
+ cp $(srcdir)/config/m68k/aux-exit.c aux-exit.c
+
+crt1.o: $(srcdir)/config/m68k/aux-crt1.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -o crt1.o -c \
+ -fno-omit-frame-pointer $(srcdir)/config/m68k/aux-crt1.c
+
+mcrt1.o: $(srcdir)/config/m68k/aux-crt1.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -o mcrt1.o -c \
+ -fno-omit-frame-pointer -DMCRT1 $(srcdir)/config/m68k/aux-crt1.c
+
+maccrt1.o: $(srcdir)/config/m68k/aux-crt1.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -o maccrt1.o -c \
+ -fno-omit-frame-pointer -DMACCRT1 $(srcdir)/config/m68k/aux-crt1.c
+
+crt2.o: $(srcdir)/config/m68k/aux-crt2.asm $(GCC_PASSES)
+ $(AS) -o crt2.o $(srcdir)/config/m68k/aux-crt2.asm
+
+crtn.o: $(srcdir)/config/m68k/aux-crtn.asm $(GCC_PASSES)
+ $(AS) -o crtn.o $(srcdir)/config/m68k/aux-crtn.asm
+
+low.gld: $(srcdir)/config/m68k/aux-low.gld
+ sed -e 's|@libdir@|$(libdir)|' -e 's|@tooldir@|$(tooldir)|' \
+ -e 's|@local_prefix@|$(local_prefix)|' \
+ $(srcdir)/config/m68k/aux-low.gld > tmp-low.gld
+ mv tmp-low.gld low.gld
diff --git a/gnu/usr.bin/gcc/config/m68k/t-linux-aout b/gnu/usr.bin/gcc/config/m68k/t-linux-aout
new file mode 100644
index 00000000000..4ef9e1acaed
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/t-linux-aout
@@ -0,0 +1,5 @@
+# Don't make libgcc1.a
+LIBGCC1 =
+CROSS_LIBGCC1 =
+# On GNU/Linux we can print long double
+ENQUIRE_CFLAGS = -DNO_MEM -O0
diff --git a/gnu/usr.bin/gcc/config/m68k/t-mot3300 b/gnu/usr.bin/gcc/config/m68k/t-mot3300
new file mode 100644
index 00000000000..2fc11858d58
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/t-mot3300
@@ -0,0 +1,10 @@
+MULTILIB_OPTIONS=m68000/m68020 msoft-float
+MULTILIB_DIRNAMES=
+MULTILIB_MATCHES=m68000=mc68000 m68000=m68302 m68000=m68332 m68020=mc68020 m68020=m68040
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+
+CRT0_S = $(srcdir)/config/m68k/mot3300-crt0.S
+MCRT0_S = $(srcdir)/config/m68k/mot3300Mcrt0.S
+CRT0STUFF_T_CFLAGS = -DMOTOROLA -DSGS_CMP_ORDER
diff --git a/gnu/usr.bin/gcc/config/m68k/t-mot3300-gald b/gnu/usr.bin/gcc/config/m68k/t-mot3300-gald
new file mode 100644
index 00000000000..435afc49e65
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/t-mot3300-gald
@@ -0,0 +1,13 @@
+T_CPPFLAGS = -DUSE_GAS -DUSE_GLD
+TARGET_LIBGCC2_CFLAGS = -DUSE_GAS
+
+MULTILIB_OPTIONS=m68000/m68020 msoft-float
+MULTILIB_DIRNAMES=
+MULTILIB_MATCHES=m68000=mc68000 m68000=m68302 m68000=m68332 m68020=mc68020 m68020=m68040
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+
+CRT0_S = $(srcdir)/config/m68k/mot3300-crt0.S
+MCRT0_S = $(srcdir)/config/m68k/mot3300Mcrt0.S
+CRT0STUFF_T_CFLAGS =
diff --git a/gnu/usr.bin/gcc/config/m68k/t-mot3300-gas b/gnu/usr.bin/gcc/config/m68k/t-mot3300-gas
new file mode 100644
index 00000000000..525667452e2
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/t-mot3300-gas
@@ -0,0 +1,13 @@
+T_CPPFLAGS = -DUSE_GAS
+TARGET_LIBGCC2_CFLAGS = -DUSE_GAS
+
+MULTILIB_OPTIONS=m68000/m68020 msoft-float
+MULTILIB_DIRNAMES=
+MULTILIB_MATCHES=m68000=mc68000 m68000=m68302 m68000=m68332 m68020=mc68020 m68020=m68040
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+
+CRT0_S = $(srcdir)/config/m68k/mot3300-crt0.S
+MCRT0_S = $(srcdir)/config/m68k/mot3300Mcrt0.S
+CRT0STUFF_T_CFLAGS =
diff --git a/gnu/usr.bin/gcc/config/m68k/t-mot3300-gld b/gnu/usr.bin/gcc/config/m68k/t-mot3300-gld
new file mode 100644
index 00000000000..8cc3ed6f250
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/t-mot3300-gld
@@ -0,0 +1,12 @@
+T_CPPFLAGS = -DUSE_GLD
+
+MULTILIB_OPTIONS=m68000/m68020 msoft-float
+MULTILIB_DIRNAMES=
+MULTILIB_MATCHES=m68000=mc68000 m68000=m68302 m68000=m68332 m68020=mc68020 m68020=m68040
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+
+CRT0_S = $(srcdir)/config/m68k/mot3300-crt0.S
+MCRT0_S = $(srcdir)/config/m68k/mot3300Mcrt0.S
+CRT0STUFF_T_CFLAGS = -DMOTOROLA -DSGS_CMP_ORDER
diff --git a/gnu/usr.bin/gcc/config/m68k/x-mot3300-gas b/gnu/usr.bin/gcc/config/m68k/x-mot3300-gas
new file mode 100644
index 00000000000..cf2797773df
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/x-mot3300-gas
@@ -0,0 +1,12 @@
+ALLOCA=alloca.o
+
+# This disables the long/short jump optimization.
+# I use sysV68 R3V7.1 RM04 (phdm@info.ucl.ac.be)
+# Since ss-950318, with jump optimization enabled, "as" issues a warning
+# when assembling combine.s :
+# aline nnnnn : Warning: Table overflow: some optimizations lost (SDIs)
+# but later "ld" complains with
+# ld: relocation entry found for non-relocatable symbol in combine.o
+# and the produced "cc1" fails with SIGSEGV
+# Another possible fix would be to split combine.c.
+XCFLAGS=`if [ x$@ = xcombine.o -a "${CC}" = "${OLDCC}" ]; then echo -Wa,-j; fi`
diff --git a/gnu/usr.bin/gcc/config/m68k/xm-aux.h b/gnu/usr.bin/gcc/config/m68k/xm-aux.h
new file mode 100644
index 00000000000..5ac1f4654d8
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m68k/xm-aux.h
@@ -0,0 +1,9 @@
+#ifndef USG
+#define USG
+#endif
+
+#ifndef AUX
+#define AUX
+#endif
+
+#include "m68k/xm-m68k.h"
diff --git a/gnu/usr.bin/gcc/config/m88k/t-dguxbcs b/gnu/usr.bin/gcc/config/m88k/t-dguxbcs
new file mode 100644
index 00000000000..c42a9bf18d5
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/m88k/t-dguxbcs
@@ -0,0 +1,28 @@
+# Specify how to create the *.asm files
+
+MOVE_ASM = moveHI15x.asm moveQI16x.asm moveSI46x.asm moveSI64n.asm \
+ moveHI48x.asm moveSI45x.asm moveSI47x.asm moveSI96x.asm \
+ moveDI96x.asm
+
+$(MOVE_ASM): $(srcdir)/config/m88k/m88k-move.sh
+ $(srcdir)/config/m88k/m88k-move.sh
+
+LIB2FUNCS_EXTRA = $(MOVE_ASM)
+LIBGCC1 = libgcc1.null
+CROSS_LIBGCC1 = libgcc1.null
+
+# In a coff environment, a link script is required for ctors and dtors.
+m88kdgux.ld: $(srcdir)/config/m88k/dgux.ld
+ rm -f m88kdgux.ld; cp $(srcdir)/config/m88k/dgux.ld ./m88kdgux.ld
+
+# A bcs crtbegin.o is needed since bcs does not
+# increment the stack pointer in the init section as elf does
+bcscrtbegin.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) gbl-ctors.h
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) -DCRT_BEGIN -DBCS \
+ -finhibit-size-directive -fno-inline-functions \
+ -g0 -c $(srcdir)/crtstuff.c -o bcscrtbegin.o
+
+# Build libgcc.a, crtbegin.o, and crtend.o as bcs objects
+GCC_FOR_TARGET = PATH=/usr/sde/m88kbcs/usr/bin/:/usr/bin TARGET_BINARY_INTERFACE=m88kbcs ./xgcc -B./ -msvr3 -D_M88KBCS_TARGET -mno-ocs-debug-info
+
+T_CFLAGS = -O -D_M88KBCS_TARGET
diff --git a/gnu/usr.bin/gcc/config/mips/r3900.h b/gnu/usr.bin/gcc/config/mips/r3900.h
new file mode 100644
index 00000000000..c1867430129
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mips/r3900.h
@@ -0,0 +1,71 @@
+/* Definitions of MIPS sub target machine for GNU compiler.
+ Toshiba r3900. You should include mips.h after this.
+
+ Copyright (C) 1989, 90-6, 1997 Free Software Foundation, Inc.
+ Contributed by Gavin Koch (gavin@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 SUBTARGET_CPP_SPEC "\
+%{!mabi=32: %{!mabi=n32: %{!mabi=64: -D__mips_eabi}}} \
+%{!msingle-float:-D__mips_soft_float} \
+%{mhard-float:%e-mhard-float not supported.} \
+%{msingle-float:%{msoft-float: \
+ %e-msingle-float and -msoft-float can not both be specified.}}"
+
+/* The following is needed because -mips3 and -mips4 set gp64 which in
+ combination with abi=eabi, causes long64 to be set. */
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mips3:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int} \
+%{mips4:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int} \
+%{!mips3:%{!mips4:%{!m4650:\
+ -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}}} "
+
+/* by default (if not mips-something-else) produce code for the r3900 */
+#define SUBTARGET_CC1_SPEC "\
+%{mhard-float:%e-mhard-float not supported.} \
+%{msingle-float:%{msoft-float: \
+ %e-msingle-float and -msoft-float can not both be specified.}}"
+
+#define TARGET_DEFAULT (MASK_SOFT_FLOAT | MASK_MIPS3900)
+#define MIPS_CPU_STRING_DEFAULT "R3900"
+#define MIPS_ISA_DEFAULT 1
+
+#define MULTILIB_DEFAULTS { "EB", "mips1", "msoft-float" }
+
+/* We use the MIPS EABI by default. */
+#define MIPS_ABI_DEFAULT ABI_EABI
+
+
+/* Debugging */
+
+#define DWARF2_DEBUGGING_INFO
+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+
+/* For the 'preferred' cases ("gN" and "ggdbN") we need to tell the
+ gnu assembler "dwarf-2" */
+
+#define SUBTARGET_ASM_DEBUGGING_SPEC "\
+%{!mmips-as: \
+ %{g:-gdwarf-2} %{g0:-gdwarf-2} %{g1:-gdwarf-2} %{g2:-gdwarf-2} %{g3:-gdwarf-2} \
+ %{ggdb:-gdwarf-2} %{ggdb0:-gdwarf-2} %{ggdb1:-gdwarf-2} %{ggdb2:-gdwarf-2} %{ggdb3:-gdwarf-2} \
+ %{gdwarf-2*:-gdwarf-2}} \
+%{gstabs:-g} %{gstabs0:-g0} %{gstabs1:-g1} %{gstabs2:-g2} %{gstabs3:-g3} \
+%{gstabs+:-g} %{gstabs+0:-g0} %{gstabs+1:-g1} %{gstabs+2:-g2} %{gstabs+3:-g3} \
+%{gcoff:-g} %{gcoff0:-g0} %{gcoff1:-g1} %{gcoff2:-g2} %{gcoff3:-g3}"
+
diff --git a/gnu/usr.bin/gcc/config/mips/rtems64.h b/gnu/usr.bin/gcc/config/mips/rtems64.h
new file mode 100644
index 00000000000..6433ed56498
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mips/rtems64.h
@@ -0,0 +1,28 @@
+/* Definitions for rtems targeting a MIPS ORION using ecoff.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Joel Sherrill (joel@OARcorp.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 "mips/elforion.h"
+
+/* Specify predefined symbols in preprocessor. */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Dmips -DMIPSEB -DR4000 -D_mips -D_MIPSEB -D_R4000 \
+ -Drtems -D__rtems__ -Asystem(rtems)"
diff --git a/gnu/usr.bin/gcc/config/mips/sni-gas.h b/gnu/usr.bin/gcc/config/mips/sni-gas.h
new file mode 100644
index 00000000000..752866536b8
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mips/sni-gas.h
@@ -0,0 +1,43 @@
+#include "mips/sni-svr4.h"
+
+/* Enable debugging. */
+#define DBX_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO
+#define MIPS_DEBUGGING_INFO
+
+#define DWARF_DEBUGGING_INFO
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
+
+/* We need to use .esize and .etype instead of .size and .type to
+ avoid conflicting with ELF directives. These are only recognized
+ by gas, anyhow, not the native assembler. */
+#undef PUT_SDB_SIZE
+#define PUT_SDB_SIZE(a) \
+do { \
+ extern FILE *asm_out_text_file; \
+ fprintf (asm_out_text_file, "\t.esize\t%d;", (a)); \
+} while (0)
+
+#undef PUT_SDB_TYPE
+#define PUT_SDB_TYPE(a) \
+do { \
+ extern FILE *asm_out_text_file; \
+ fprintf (asm_out_text_file, "\t.etype\t0x%x;", (a)); \
+} while (0)
+
+
+/* This is how to equate one symbol to another symbol. The syntax used is
+ `SYM1=SYM2'. Note that this is different from the way equates are done
+ with most svr4 assemblers, where the syntax is `.set SYM1,SYM2'. */
+
+#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
+ do { fprintf ((FILE), "\t"); \
+ assemble_name (FILE, LABEL1); \
+ fprintf (FILE, " = "); \
+ assemble_name (FILE, LABEL2); \
+ fprintf (FILE, "\n"); \
+ } while (0)
+
+
+
diff --git a/gnu/usr.bin/gcc/config/mips/sni-svr4.h b/gnu/usr.bin/gcc/config/mips/sni-svr4.h
new file mode 100644
index 00000000000..f42a882fb82
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mips/sni-svr4.h
@@ -0,0 +1,97 @@
+/* Definitions of target machine for GNU compiler. SNI SINIX version.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Marco Walther (Marco.Walther@mch.sni.de).
+
+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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#define MIPS_SVR4
+
+#define CPP_PREDEFINES "\
+-Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_SVR4 \
+-D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_SVR4 \
+-Asystem(unix) -Asystem(svr4) -Acpu(mips) -Amachine(mips)"
+
+#define SUBTARGET_CPP_SIZE_SPEC "\
+-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int"
+
+#define LINK_SPEC "\
+%{G*} \
+%{!mgas: \
+ %{dy} %{dn}}"
+
+#define LIB_SPEC "\
+ %{p:-lprof1} \
+ %{!p:%{pg:-lprof1} \
+ %{!pg:-L/usr/ccs/lib/ -lc /usr/ccs/lib/crtn.o%s}}"
+
+#define STARTFILE_SPEC "\
+ %{pg:gcrt0.o%s} \
+ %{!pg:%{p:mcrt0.o%s} \
+ %{!p:/usr/ccs/lib/crt1.o /usr/ccs/lib/crti.o /usr/ccs/lib/values-Xt.o%s}}"
+
+/* Mips System V.4 doesn't have a getpagesize() function needed by the
+ trampoline code, so use the POSIX sysconf function to get it.
+ This is only done when compiling the trampoline code. */
+
+#ifdef L_trampoline
+#include <unistd.h>
+
+#define getpagesize() sysconf(_SC_PAGE_SIZE)
+#endif /* L_trampoline */
+
+/* Use atexit for static constructors/destructors, instead of defining
+ our own exit function. */
+#define HAVE_ATEXIT
+
+/* Generate calls to memcpy, etc., not bcopy, etc. */
+#define TARGET_MEM_FUNCTIONS
+
+#define OBJECT_FORMAT_ELF
+
+#define TARGET_DEFAULT MASK_ABICALLS
+#define ABICALLS_ASM_OP ".option pic2"
+
+#define MACHINE_TYPE "SNI running SINIX 5.42"
+
+#define MIPS_DEFAULT_GVALUE 0
+
+#define NM_FLAGS "-p"
+
+/* wir haben ein Problem, wenn in einem Assembler-File keine .text-section
+ erzeugt wird. Dann landen diese Pseudo-Labels in irgendeiner anderen
+ section, z.B. .reginfo. Das macht den ld sehr ungluecklich. */
+
+#define ASM_IDENTIFY_GCC(mw_stream) \
+ fprintf(mw_stream, "\t.ident \"gcc2_compiled.\"\n");
+
+#define ASM_IDENTIFY_LANGUAGE(STREAM)
+
+#define ASM_LONG ".word\t"
+#define ASM_GLOBAL ".rdata\n\t\t.globl\t"
+
+#include "mips/mips.h"
+
+/* We do not want to run mips-tfile! */
+#undef ASM_FINAL_SPEC
+
+#undef OBJECT_FORMAT_COFF
+
+/* We don't support debugging info for now. */
+#undef DBX_DEBUGGING_INFO
+#undef SDB_DEBUGGING_INFO
+#undef MIPS_DEBUGGING_INFO
+#undef PREFERRED_DEBUGGING_TYPE
diff --git a/gnu/usr.bin/gcc/config/mips/x-sni-svr4 b/gnu/usr.bin/gcc/config/mips/x-sni-svr4
new file mode 100644
index 00000000000..f986f88162f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mips/x-sni-svr4
@@ -0,0 +1,18 @@
+# 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).
+# -Olimit is so the user can use -O2. Down with fixed
+# size tables!
+
+CC = $(OLDCC)
+OPT =
+OLDCC = cc -Olimit 3000 $(OPT)
+
+X_CFLAGS = -DNO_SYS_SIGLIST
+
+# Show we need to use the C version of ALLOCA
+# The SVR3 configurations have it, but the SVR4 configurations don't.
+# For now, just try using it for all SVR* configurations.
+ALLOCA = alloca.o
diff --git a/gnu/usr.bin/gcc/config/mn10200/divmod.c b/gnu/usr.bin/gcc/config/mn10200/divmod.c
new file mode 100644
index 00000000000..6faa09102b5
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10200/divmod.c
@@ -0,0 +1,50 @@
+long udivmodsi4 ();
+
+long
+__divsi3 (long a, long b)
+{
+ int neg = 0;
+ long res;
+
+ if (a < 0)
+ {
+ a = -a;
+ neg = !neg;
+ }
+
+ if (b < 0)
+ {
+ b = -b;
+ neg = !neg;
+ }
+
+ res = udivmodsi4 (a, b, 0);
+
+ if (neg)
+ res = -res;
+
+ return res;
+}
+
+long
+__modsi3 (long a, long b)
+{
+ int neg = 0;
+ long res;
+
+ if (a < 0)
+ {
+ a = -a;
+ neg = 1;
+ }
+
+ if (b < 0)
+ b = -b;
+
+ res = udivmodsi4 (a, b, 1);
+
+ if (neg)
+ res = -res;
+
+ return res;
+}
diff --git a/gnu/usr.bin/gcc/config/mn10200/lib1funcs.asm b/gnu/usr.bin/gcc/config/mn10200/lib1funcs.asm
new file mode 100644
index 00000000000..ff98fcc0ca2
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10200/lib1funcs.asm
@@ -0,0 +1,609 @@
+/* libgcc1 routines for Matsushita mn10200.
+ Copyright (C) 1997 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.
+
+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. */
+
+#ifdef L_divhi3
+ /* Derive signed division/modulo from unsigned "divu" instruction. */
+ .text
+ .globl ___divhi3
+ .type ___divhi3,@function
+___divhi3:
+
+ /* We're going to need some scratch registers, so save d2/d3
+ into the stack. */
+ add -8,a3
+ movx d2,(0,a3)
+ movx d3,(4,a3)
+
+ /* Loading zeros into registers now allows us to use them
+ in the compare instructions, which saves a total of
+ two bytes (egad). */
+ sub d3,d3
+ sub d2,d2
+ sub a0,a0
+
+ /* If first operand is negative, then make it positive.
+ It will be contained in d2 just before .L1.
+
+ a0 tells us if the first operand was negated. */
+ cmp d2,d0
+ bge .L0
+ sub d0,d2
+ mov 1,a0
+ bra .L1
+.L0:
+ mov d0,d2
+.L1:
+ /* If the second operand is negative, then make it positive.
+ It will be contained in d3 just before .L3.
+
+ d0 tells us if the second operand was negated. */
+ cmp d3,d1
+ bge .L2
+ sub d1,d3
+ mov 1,d0
+ bra .L3
+.L2:
+ sub d0,d0
+ mov d1,d3
+.L3:
+ /* Loading d1 with zero here allows us to save one byte
+ in the comparison below. */
+
+ sub d1,d1
+
+ /* Make sure to clear the mdr register, then do the unsigned
+ division. Result will be in d2/mdr. */
+ mov d1,mdr
+ divu d3,d2
+
+ /* Negate the remainder based on the first argument negation
+ flag only. */
+ cmp d1,a0
+ beq .L4
+ mov mdr,d3
+ sub d3,d1
+ bra .L5
+.L4:
+ mov mdr,d1
+
+.L5:
+ /* Negate the result if either, but not both of the inputs
+ were negated. */
+ mov a0,d3
+ xor d3,d0
+ beq .L6
+ sub d0,d0
+ sub d2,d0
+ bra .L7
+.L6:
+ mov d2,d0
+.L7:
+
+ /* Restore our scratch registers, deallocate our stack and return. */
+ movx (0,a3),d2
+ movx (4,a3),d3
+ add 8,a3
+ rts
+ .size ___divhi3,.-___divhi3
+#endif
+
+#ifdef L_modhi3
+ .text
+ .globl ___modhi3
+ .type ___modhi3,@function
+___modhi3:
+ jsr ___divhi3
+ mov d1,d0
+ rts
+ .size ___modhi3,.-___modhi3
+#endif
+
+#ifdef L_addsi3
+ .text
+ .globl ___addsi3
+ .type ___addsi3,@function
+___addsi3:
+ add -4,a3
+ movx d2,(0,a3)
+ mov (8,a3),d2
+ add d2,d0
+ mov (10,a3),d2
+ addc d2,d1
+ movx (0,a3),d2
+ add 4,a3
+ rts
+
+ .size ___addsi3,.-___addsi3
+#endif
+
+#ifdef L_subsi3
+ .text
+ .globl ___subsi3
+ .type ___subsi3,@function
+___subsi3:
+ add -4,a3
+ movx d2,(0,a3)
+ mov (8,a3),d2
+ sub d2,d0
+ mov (10,a3),d2
+ subc d2,d1
+ movx (0,a3),d2
+ add 4,a3
+ rts
+
+ .size ___subsi3,.-___subsi3
+#endif
+
+#ifdef L_mulsi3
+ .text
+ .globl ___mulsi3
+ .type ___mulsi3,@function
+___mulsi3:
+ add -4,a3
+ mov a1,(0,a3)
+ mov d0,a0
+ /* Multiply arg0 msb with arg1 lsb.
+ arg0 msb is in register d1,
+ arg1 lsb is in memory. */
+ mov (8,a3),d0
+ mulu d0,d1
+ mov d1,a1
+
+ /* Multiply arg0 lsb with arg1 msb.
+ arg0 msb is in register a0,
+ arg1 lsb is in memory. */
+ mov a0,d0
+ mov (10,a3),d1
+ mulu d0,d1
+
+ /* Add the cross products. */
+ add d1,a1
+
+ /* Now multiply arg0 lsb with arg1 lsb. */
+ mov (8,a3),d1
+ mulu d1,d0
+
+ /* Add in the upper 16 bits to the cross product sum. */
+ mov mdr,d1
+ add a1,d1
+ mov (0,a3),a1
+ add 4,a3
+ rts
+
+ .size ___mulsi3,.-___mulsi3
+#endif
+
+#ifdef L_ashlsi3
+ .text
+ .globl ___ashlsi3
+ .type ___ashlsi3,@function
+___ashlsi3:
+ mov (4,a3),a0
+ cmp 0,a0
+ beq .L0
+.L1:
+ add d0,d0
+ addc d1,d1
+ add -1,a0
+ bne .L1
+.L0:
+ rts
+
+ .size ___ashlsi3,.-___ashlsi3
+#endif
+
+#ifdef L_lshrsi3
+ .text
+ .globl ___lshrsi3
+ .type ___lshrsi3,@function
+___lshrsi3:
+ mov (4,a3),a0
+ cmp 0,a0
+ beq .L0
+.L1:
+ lsr d1
+ ror d0
+ add -1,a0
+ bne .L1
+.L0:
+ rts
+
+ .size ___lshrsi3,.-___lshrsi3
+#endif
+
+#ifdef L_ashrsi3
+ .text
+ .globl ___ashrsi3
+ .type ___ashrsi3,@function
+___ashrsi3:
+ mov (4,a3),a0
+ cmp 0,a0
+ beq .L0
+.L1:
+ asr d1
+ ror d0
+ add -1,a0
+ bne .L1
+.L0:
+ rts
+
+ .size ___ashrsi3,.-___ashrsi3
+#endif
+
+/* All functions beyond this point pass their arguments in registers! */
+#ifdef L_negsi2_d0
+ .text
+ .globl ___negsi2_d0
+ .type ___negsi2_d0,@function
+___negsi2_d0:
+ add -8,a3
+ movx d3,(0,a3)
+ movx d2,(4,a3)
+ mov d0,d2
+ mov d1,d3
+ sub d0,d0
+ sub d1,d1
+ sub d2,d0
+ subc d3,d1
+ movx (0,a3),d3
+ movx (4,a3),d2
+ add 8,a3
+ rts
+
+ .size ___negsi2_d0,.-___negsi2_d0
+#endif
+
+#ifdef L_negsi2_d2
+ .text
+ .globl ___negsi2_d2
+ .type ___negsi2_d2,@function
+___negsi2_d2:
+ add -8,a3
+ movx d1,(0,a3)
+ movx d0,(4,a3)
+ mov d2,d0
+ mov d3,d1
+ sub d2,d2
+ sub d3,d3
+ sub d0,d2
+ subc d1,d3
+ movx (0,a3),d1
+ movx (4,a3),d0
+ add 8,a3
+ rts
+
+ .size ___negsi2_d2,.-___negsi2_d2
+#endif
+
+#ifdef L_zero_extendpsisi2_d0
+ .text
+ .globl ___zero_extendpsisi2_d0
+ .type ___zero_extendpsisi2_d0,@function
+___zero_extendpsisi2_d0:
+ add -4,a3
+ movx d0,(0,a3)
+ movbu (2,a3),d1
+ add 4,a3
+ rts
+
+ .size ___zero_extendpsisi2_d0,.-___zero_extendpsisi2_d0
+#endif
+
+#ifdef L_zero_extendpsisi2_d2
+ .text
+ .globl ___zero_extendpsisi2_d2
+ .type ___zero_extendpsisi2_d2,@function
+___zero_extendpsisi2_d2:
+ add -4,a3
+ movx d2,(0,a3)
+ movbu (2,a3),d3
+ add 4,a3
+ rts
+
+ .size ___zero_extendpsisi2_d2,.-___zero_extendpsisi2_d2
+#endif
+
+#ifdef L_sign_extendpsisi2_d0
+ .text
+ .globl ___sign_extendpsisi2_d0
+ .type ___sign_extendpsisi2_d0,@function
+___sign_extendpsisi2_d0:
+ add -4,a3
+ movx d0,(0,a3)
+ movb (2,a3),d1
+ add 4,a3
+ rts
+
+ .size ___sign_extendpsisi2_d0,.-___sign_extendpsisi2_d0
+#endif
+
+#ifdef L_sign_extendpsisi2_d2
+ .text
+ .globl ___sign_extendpsisi2_d2
+ .type ___sign_extendpsisi2_d2,@function
+___sign_extendpsisi2_d2:
+ add -4,a3
+ movx d2,(0,a3)
+ movb (2,a3),d3
+ add 4,a3
+ rts
+
+ .size ___sign_extendpsisi2_d2,.-___sign_extendpsisi2_d2
+#endif
+
+#ifdef L_truncsipsi2_d0_d0
+ .text
+ .globl ___truncsipsi2_d0_d0
+ .type ___truncsipsi2_d0_d0,@function
+___truncsipsi2_d0_d0:
+ add -4,a3
+ mov d0,(a3)
+ mov d1,(2,a3)
+ movx (0,a3),d0
+ add 4,a3
+ rts
+
+ .size ___truncsipsi2_d0_d0,.-___truncsipsi2_d0_d0
+#endif
+
+#ifdef L_truncsipsi2_d0_d1
+ .text
+ .globl ___truncsipsi2_d0_d1
+ .type ___truncsipsi2_d0_d1,@function
+___truncsipsi2_d0_d1:
+ add -4,a3
+ mov d0,(a3)
+ mov d1,(2,a3)
+ movx (0,a3),d1
+ add 4,a3
+ rts
+
+ .size ___truncsipsi2_d0_d1,.-___truncsipsi2_d0_d1
+#endif
+
+#ifdef L_truncsipsi2_d0_d2
+ .text
+ .globl ___truncsipsi2_d0_d2
+ .type ___truncsipsi2_d0_d2,@function
+___truncsipsi2_d0_d2:
+ add -4,a3
+ mov d0,(a3)
+ mov d1,(2,a3)
+ movx (0,a3),d2
+ add 4,a3
+ rts
+
+ .size ___truncsipsi2_d0_d2,.-___truncsipsi2_d0_d2
+#endif
+
+#ifdef L_truncsipsi2_d0_d3
+ .text
+ .globl ___truncsipsi2_d0_d3
+ .type ___truncsipsi2_d0_d3,@function
+___truncsipsi2_d0_d3:
+ add -4,a3
+ mov d0,(a3)
+ mov d1,(2,a3)
+ movx (0,a3),d3
+ add 4,a3
+ rts
+
+ .size ___truncsipsi2_d0_d3,.-___truncsipsi2_d0_d3
+#endif
+
+#ifdef L_truncsipsi2_d2_d0
+ .text
+ .globl ___truncsipsi2_d2_d0
+ .type ___truncsipsi2_d2_d0,@function
+___truncsipsi2_d2_d0:
+ add -4,a3
+ mov d2,(a3)
+ mov d3,(2,a3)
+ movx (0,a3),d0
+ add 4,a3
+ rts
+
+ .size ___truncsipsi2_d2_d0,.-___truncsipsi2_d2_d0
+#endif
+
+#ifdef L_truncsipsi2_d2_d1
+ .text
+ .globl ___truncsipsi2_d2_d1
+ .type ___truncsipsi2_d2_d1,@function
+___truncsipsi2_d2_d1:
+ add -4,a3
+ mov d2,(a3)
+ mov d3,(2,a3)
+ movx (0,a3),d1
+ add 4,a3
+ rts
+
+ .size ___truncsipsi2_d2_d1,.-___truncsipsi2_d2_d1
+#endif
+
+#ifdef L_truncsipsi2_d2_d2
+ .text
+ .globl ___truncsipsi2_d2_d2
+ .type ___truncsipsi2_d2_d2,@function
+___truncsipsi2_d2_d2:
+ add -4,a3
+ mov d2,(a3)
+ mov d3,(2,a3)
+ movx (0,a3),d2
+ add 4,a3
+ rts
+
+ .size ___truncsipsi2_d2_d2,.-___truncsipsi2_d2_d2
+#endif
+
+#ifdef L_truncsipsi2_d2_d3
+ .text
+ .globl ___truncsipsi2_d2_d3
+ .type ___truncsipsi2_d2_d3,@function
+___truncsipsi2_d2_d3:
+ add -4,a3
+ mov d2,(a3)
+ mov d3,(2,a3)
+ movx (0,a3),d3
+ add 4,a3
+ rts
+
+ .size ___truncsipsi2_d2_d3,.-___truncsipsi2_d2_d3
+#endif
+
+
+#ifdef L_cmpsi2
+ .text
+ .globl ___cmpsi2
+ .type ___cmpsi2,@function
+___cmpsi2:
+ add -4,a3
+ mov a1,(0,a3)
+ mov (10,a3),a1
+ mov (8,a3),a0
+ cmp a1,d1
+ blt .L9
+ bgt .L6
+ cmp a0,d0
+ bcc .L5
+.L9:
+ sub d0,d0
+ jmp .L8
+.L5:
+ cmp a0,d0
+ bhi .L6
+ mov 1,d0
+ jmp .L8
+.L6:
+ mov 2,d0
+.L8:
+ mov (0,a3),a1
+ add 4,a3
+ rts
+ .size ___cmpsi2,.-___cmpsi2
+#endif
+
+#ifdef L_ucmpsi2
+ .text
+ .globl ___ucmpsi2
+ .type ___ucmpsi2,@function
+___ucmpsi2:
+ add -4,a3
+ mov a1,(0,a3)
+ mov (10,a3),a1
+ mov (8,a3),a0
+ cmp a1,d1
+ bcs .L9
+ bhi .L6
+ cmp a0,d0
+ bcc .L5
+.L9:
+ sub d0,d0
+ jmp .L8
+.L5:
+ cmp a0,d0
+ bhi .L6
+ mov 1,d0
+ jmp .L8
+.L6:
+ mov 2,d0
+.L8:
+ mov (0,a3),a1
+ add 4,a3
+ rts
+ .size ___ucmpsi2,.-___ucmpsi2
+#endif
+
+
+#ifdef L_prologue
+ .text
+ .globl ___prologue
+ .type ___prologue,@function
+___prologue:
+ mov (0,a3),a0
+ add -16,a3
+ movx d2,(4,a3)
+ movx d3,(8,a3)
+ mov a1,(12,a3)
+ mov a2,(16,a3)
+ mov a0,(0,a3)
+ rts
+ .size ___prologue,.-___prologue
+#endif
+
+#ifdef L_epilogue_a0
+ .text
+ .globl ___epilogue_a0
+ .type ___epilogue_a0,@function
+___epilogue_a0:
+ mov (0,a3),a0
+ movx (4,a3),d2
+ movx (8,a3),d3
+ mov (12,a3),a1
+ mov (16,a3),a2
+ add 16,a3
+ mov a0,(0,a3)
+ rts
+ .size ___epilogue_a0,.-___epilogue_a0
+#endif
+
+#ifdef L_epilogue_d0
+ .text
+ .globl ___epilogue_d0
+ .type ___epilogue_d0,@function
+___epilogue_d0:
+ movx (0,a3),d0
+ movx (4,a3),d2
+ movx (8,a3),d3
+ mov (12,a3),a1
+ mov (16,a3),a2
+ add 16,a3
+ movx d0,(0,a3)
+ rts
+ .size ___epilogue_d0,.-___epilogue_d0
+#endif
+
+#ifdef L_epilogue_noreturn
+ .text
+ .globl ___epilogue_noreturn
+ .type ___epilogue_noreturn,@function
+___epilogue_noreturn:
+ movx (0,a3),d2
+ movx (4,a3),d3
+ mov (8,a3),a1
+ mov (12,a3),a2
+ add 16,a3
+ rts
+ .size ___epilogue_noreturn,.-___epilogue_noreturn
+#endif
diff --git a/gnu/usr.bin/gcc/config/mn10200/mn10200.c b/gnu/usr.bin/gcc/config/mn10200/mn10200.c
new file mode 100644
index 00000000000..5435f773c8d
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10200/mn10200.c
@@ -0,0 +1,1532 @@
+/* Subroutines for insn-output.c for Matsushita MN10200 series
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Jeff Law (law@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 "config.h"
+#include <stdio.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 "flags.h"
+#include "recog.h"
+#include "expr.h"
+#include "tree.h"
+#include "obstack.h"
+
+/* Global registers known to hold the value zero.
+
+ Normally we'd depend on CSE and combine to put zero into a
+ register and re-use it.
+
+ However, on the mn10x00 processors we implicitly use the constant
+ zero in tst instructions, so we might be able to do better by
+ loading the value into a register in the prologue, then re-useing
+ that register throughout the function.
+
+ We could perform similar optimizations for other constants, but with
+ gcse due soon, it doesn't seem worth the effort.
+
+ These variables hold a rtx for a register known to hold the value
+ zero throughout the entire function, or NULL if no register of
+ the appropriate class has such a value throughout the life of the
+ function. */
+rtx zero_dreg;
+rtx zero_areg;
+
+/* Note whether or not we need an out of line epilogue. */
+static int out_of_line_epilogue;
+
+/* Indicate this file was compiled by gcc and what optimization
+ level was used. */
+void
+asm_file_start (file)
+ FILE *file;
+{
+ fprintf (file, "#\tGCC For the Matsushita MN10200\n");
+ if (optimize)
+ fprintf (file, "# -O%d\n", optimize);
+ else
+ fprintf (file, "\n\n");
+ output_file_directive (file, main_input_filename);
+}
+
+/* Print operand X using operand code CODE to assembly language output file
+ FILE. */
+
+void
+print_operand (file, x, code)
+ FILE *file;
+ rtx x;
+ int code;
+{
+ switch (code)
+ {
+ case 'b':
+ case 'B':
+ /* These are normal and reversed branches. */
+ switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
+ {
+ case NE:
+ fprintf (file, "ne");
+ break;
+ case EQ:
+ fprintf (file, "eq");
+ break;
+ case GE:
+ fprintf (file, "ge");
+ break;
+ case GT:
+ fprintf (file, "gt");
+ break;
+ case LE:
+ fprintf (file, "le");
+ break;
+ case LT:
+ fprintf (file, "lt");
+ break;
+ case GEU:
+ fprintf (file, "cc");
+ break;
+ case GTU:
+ fprintf (file, "hi");
+ break;
+ case LEU:
+ fprintf (file, "ls");
+ break;
+ case LTU:
+ fprintf (file, "cs");
+ break;
+ default:
+ abort ();
+ }
+ break;
+ case 'C':
+ /* This is used for the operand to a call instruction;
+ if it's a REG, enclose it in parens, else output
+ the operand normally. */
+ if (GET_CODE (x) == REG)
+ {
+ fputc ('(', file);
+ print_operand (file, x, 0);
+ fputc (')', file);
+ }
+ else
+ print_operand (file, x, 0);
+ break;
+
+ /* These are the least significant word in a 32bit value.
+ 'o' allows us to sign extend a constant if doing so
+ makes for more compact code. */
+ case 'L':
+ case 'o':
+ switch (GET_CODE (x))
+ {
+ case MEM:
+ fputc ('(', file);
+ output_address (XEXP (x, 0));
+ fputc (')', file);
+ break;
+
+ case REG:
+ fprintf (file, "%s", reg_names[REGNO (x)]);
+ break;
+
+ case SUBREG:
+ fprintf (file, "%s",
+ reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)]);
+ break;
+
+ case CONST_DOUBLE:
+ if (code == 'L')
+ {
+ long val;
+ REAL_VALUE_TYPE rv;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
+ print_operand_address (file, GEN_INT (val & 0xffff));
+ }
+ else
+ {
+ long val;
+ REAL_VALUE_TYPE rv;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
+
+ val &= 0xffff;
+ val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000;
+ print_operand_address (file, GEN_INT (val));
+ }
+ break;
+
+ case CONST_INT:
+ if (code == 'L')
+ print_operand_address (file, GEN_INT ((INTVAL (x) & 0xffff)));
+ else
+ {
+ unsigned int val = INTVAL (x) & 0xffff;
+ val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000;
+ print_operand_address (file, GEN_INT (val));
+ }
+ break;
+ default:
+ abort ();
+ }
+ break;
+
+ /* Similarly, but for the most significant word. */
+ case 'H':
+ case 'h':
+ switch (GET_CODE (x))
+ {
+ case MEM:
+ fputc ('(', file);
+ x = adj_offsettable_operand (x, 2);
+ output_address (XEXP (x, 0));
+ fputc (')', file);
+ break;
+
+ case REG:
+ fprintf (file, "%s", reg_names[REGNO (x) + 1]);
+ break;
+
+ case SUBREG:
+ fprintf (file, "%s",
+ reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)] + 1);
+ break;
+
+ case CONST_DOUBLE:
+ if (code == 'H')
+ {
+ long val;
+ REAL_VALUE_TYPE rv;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
+
+ print_operand_address (file, GEN_INT ((val >> 16) & 0xffff));
+ }
+ else
+ {
+ long val;
+ REAL_VALUE_TYPE rv;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
+
+ val = (val >> 16) & 0xffff;
+ val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000;
+
+ print_operand_address (file, GEN_INT (val));
+ }
+ break;
+
+ case CONST_INT:
+ if (code == 'H')
+ print_operand_address (file,
+ GEN_INT ((INTVAL (x) >> 16) & 0xffff));
+ else
+ {
+ unsigned int val = (INTVAL (x) >> 16) & 0xffff;
+ val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000;
+
+ print_operand_address (file, GEN_INT (val));
+ }
+ break;
+ default:
+ abort ();
+ }
+ break;
+
+ /* Output ~CONST_INT. */
+ case 'N':
+ if (GET_CODE (x) != CONST_INT)
+ abort ();
+ fprintf (file, "%d", ~INTVAL (x));
+ break;
+
+ /* An address which can not be register indirect, if it is
+ register indirect, then turn it into reg + disp. */
+ case 'A':
+ if (GET_CODE (x) != MEM)
+ abort ();
+ if (GET_CODE (XEXP (x, 0)) == REG)
+ x = gen_rtx (PLUS, PSImode, XEXP (x, 0), GEN_INT (0));
+ else
+ x = XEXP (x, 0);
+ fputc ('(', file);
+ output_address (x);
+ fputc (')', file);
+ break;
+
+ case 'Z':
+ print_operand (file, XEXP (x, 1), 0);
+ break;
+
+ /* More cases where we can sign-extend a CONST_INT if it
+ results in more compact code. */
+ case 's':
+ case 'S':
+ if (GET_CODE (x) == CONST_INT)
+ {
+ int val = INTVAL (x);
+
+ if (code == 's')
+ x = GEN_INT (((val & 0xffff) ^ (~0x7fff)) + 0x8000);
+ else
+ x = GEN_INT (((val & 0xff) ^ (~0x7f)) + 0x80);
+ }
+ /* FALL THROUGH */
+ default:
+ switch (GET_CODE (x))
+ {
+ case MEM:
+ fputc ('(', file);
+ output_address (XEXP (x, 0));
+ fputc (')', file);
+ break;
+
+ case REG:
+ fprintf (file, "%s", reg_names[REGNO (x)]);
+ break;
+
+ case SUBREG:
+ fprintf (file, "%s",
+ reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)]);
+ break;
+
+ case CONST_INT:
+ case CONST_DOUBLE:
+ case SYMBOL_REF:
+ case CONST:
+ case LABEL_REF:
+ case CODE_LABEL:
+ print_operand_address (file, x);
+ break;
+ default:
+ abort ();
+ }
+ break;
+ }
+}
+
+/* Output assembly language output for the address ADDR to FILE. */
+
+void
+print_operand_address (file, addr)
+ FILE *file;
+ rtx addr;
+{
+ switch (GET_CODE (addr))
+ {
+ case REG:
+ print_operand (file, addr, 0);
+ break;
+ case PLUS:
+ {
+ rtx base, index;
+ /* The base and index could be in any order, so we have
+ to figure out which is the base and which is the index.
+ Uses the same code as GO_IF_LEGITIMATE_ADDRESS. */
+ if (REG_P (XEXP (addr, 0))
+ && REG_OK_FOR_BASE_P (XEXP (addr, 0)))
+ base = XEXP (addr, 0), index = XEXP (addr, 1);
+ else if (REG_P (XEXP (addr, 1))
+ && REG_OK_FOR_BASE_P (XEXP (addr, 1)))
+ base = XEXP (addr, 1), index = XEXP (addr, 0);
+ else
+ abort ();
+ print_operand (file, index, 0);
+ fputc (',', file);
+ print_operand (file, base, 0);;
+ break;
+ }
+ case SYMBOL_REF:
+ output_addr_const (file, addr);
+ break;
+ default:
+ output_addr_const (file, addr);
+ break;
+ }
+}
+
+/* Count the number of tst insns which compare an address register
+ with zero. */
+static void
+count_tst_insns (areg_countp)
+ int *areg_countp;
+{
+ rtx insn;
+
+ /* Assume no tst insns exist. */
+ *areg_countp = 0;
+
+ /* If not optimizing, then quit now. */
+ if (!optimize)
+ return;
+
+ /* Walk through all the insns. */
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ rtx pat;
+
+ /* Ignore anything that is not a normal INSN. */
+ if (GET_CODE (insn) != INSN)
+ continue;
+
+ /* Ignore anything that isn't a SET. */
+ pat = PATTERN (insn);
+ if (GET_CODE (pat) != SET)
+ continue;
+
+ /* Check for a tst insn. */
+ if (SET_DEST (pat) == cc0_rtx
+ && GET_CODE (SET_SRC (pat)) == REG
+ && REGNO_REG_CLASS (REGNO (SET_SRC (pat))) == ADDRESS_REGS)
+ (*areg_countp)++;
+ }
+}
+
+/* Return the total size (in bytes) of the current function's frame.
+ This is the size of the register save area + the size of locals,
+ spills, etc. */
+int
+total_frame_size ()
+{
+ unsigned int size = get_frame_size ();
+ unsigned int outgoing_args_size = current_function_outgoing_args_size;
+ int i;
+
+ /* First figure out if we're going to use an out of line
+ prologue, if so we have to make space for all the
+ registers, even if we don't use them. */
+ if (optimize && !current_function_needs_context && !frame_pointer_needed)
+ {
+ int inline_count, outline_count;
+
+ /* Compute how many bytes an inline prologue would take.
+
+ Each address register store takes two bytes, each data register
+ store takes three bytes. */
+ inline_count = 0;
+ if (regs_ever_live[5])
+ inline_count += 2;
+ if (regs_ever_live[6])
+ inline_count += 2;
+ if (regs_ever_live[2])
+ inline_count += 3;
+ if (regs_ever_live[3])
+ inline_count += 3;
+
+ /* If this function has any stack, then the stack adjustment
+ will take two (or more) bytes. */
+ if (size || outgoing_args_size
+ || regs_ever_live[5] || regs_ever_live[6]
+ || regs_ever_live[2] || regs_ever_live[3])
+ inline_count += 2;
+
+ /* Multiply the current count by two and add one to account for the
+ epilogue insns. */
+ inline_count = inline_count * 2 + 1;
+
+ /* Now compute how many bytes an out of line sequence would take. */
+ /* A relaxed jsr will be three bytes. */
+ outline_count = 3;
+
+ /* If there are outgoing arguments, then we will need a stack
+ pointer adjustment after the call to the prologue, two
+ more bytes. */
+ outline_count += (outgoing_args_size == 0 ? 0 : 2);
+
+ /* If there is some local frame to allocate, it will need to be
+ done before the call to the prologue, two more bytes. */
+ if (get_frame_size () != 0)
+ outline_count += 2;
+
+ /* Now account for the epilogue, multiply the base count by two,
+ then deal with optimizing away the rts instruction. */
+ outline_count = outline_count * 2 + 1;
+
+ if (get_frame_size () == 0 && outgoing_args_size == 0)
+ outline_count -= 1;
+
+ /* If an out of line prologue is smaller, use it. */
+ if (inline_count > outline_count)
+ return size + outgoing_args_size + 16;
+ }
+
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ {
+ if (regs_ever_live[i] && !call_used_regs[i] && ! fixed_regs[i]
+ || (i == FRAME_POINTER_REGNUM && frame_pointer_needed))
+ size += 4;
+ }
+
+ return (size + outgoing_args_size);
+}
+
+/* Expand the prologue into RTL. */
+void
+expand_prologue ()
+{
+ unsigned int size = total_frame_size ();
+ unsigned int outgoing_args_size = current_function_outgoing_args_size;
+ int offset, i;
+
+ zero_areg = NULL_RTX;
+ zero_dreg = NULL_RTX;
+
+ /* If optimizing, see if we should do an out of line prologue/epilogue
+ sequence.
+
+ We don't support out of line prologues if the current function
+ needs a context or frame pointer. */
+ if (optimize && !current_function_needs_context && !frame_pointer_needed)
+ {
+ int inline_count, outline_count, areg_count;
+
+ /* We need to end the current sequence so that count_tst_insns can
+ look at all the insns in this function. Normally this would be
+ unsafe, but it's OK in the prologue/epilogue expanders. */
+ end_sequence ();
+
+ /* Get a count of the number of tst insns which use address
+ registers (it's not profitable to try and improve tst insns
+ which use data registers). */
+ count_tst_insns (&areg_count);
+
+ /* Now start a new sequence. */
+ start_sequence ();
+
+ /* Compute how many bytes an inline prologue would take.
+
+ Each address register store takes two bytes, each data register
+ store takes three bytes. */
+ inline_count = 0;
+ if (regs_ever_live[5])
+ inline_count += 2;
+ if (regs_ever_live[6])
+ inline_count += 2;
+ if (regs_ever_live[2])
+ inline_count += 3;
+ if (regs_ever_live[3])
+ inline_count += 3;
+
+ /* If this function has any stack, then the stack adjustment
+ will take two (or more) bytes. */
+ if (size || outgoing_args_size
+ || regs_ever_live[5] || regs_ever_live[6]
+ || regs_ever_live[2] || regs_ever_live[3])
+ inline_count += 2;
+
+ /* Multiply the current count by two and add one to account for the
+ epilogue insns. */
+ inline_count = inline_count * 2 + 1;
+
+ /* Now compute how many bytes an out of line sequence would take. */
+ /* A relaxed jsr will be three bytes. */
+ outline_count = 3;
+
+ /* If there are outgoing arguments, then we will need a stack
+ pointer adjustment after the call to the prologue, two
+ more bytes. */
+ outline_count += (outgoing_args_size == 0 ? 0 : 2);
+
+ /* If there is some local frame to allocate, it will need to be
+ done before the call to the prologue, two more bytes. */
+ if (get_frame_size () != 0)
+ outline_count += 2;
+
+ /* Now account for the epilogue, multiply the base count by two,
+ then deal with optimizing away the rts instruction. */
+ outline_count = outline_count * 2 + 1;
+
+ if (get_frame_size () == 0 && outgoing_args_size == 0)
+ outline_count -= 1;
+
+ /* If an out of line prologue is smaller, use it. */
+ if (inline_count > outline_count)
+ {
+ if (get_frame_size () != 0)
+ emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (-size + outgoing_args_size + 16)));
+ emit_insn (gen_outline_prologue_call ());
+
+ if (outgoing_args_size)
+ emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (-outgoing_args_size)));
+
+ out_of_line_epilogue = 1;
+
+ /* Determine if it is profitable to put the value zero into a register
+ for the entire function. If so, set ZERO_DREG and ZERO_AREG. */
+
+ /* First see if we could load the value into a data register
+ since that's the most efficient way. */
+ if (areg_count > 1
+ && (!regs_ever_live[2] || !regs_ever_live[3]))
+ {
+ if (!regs_ever_live[2])
+ {
+ regs_ever_live[2] = 1;
+ zero_dreg = gen_rtx (REG, HImode, 2);
+ }
+ if (!regs_ever_live[3])
+ {
+ regs_ever_live[3] = 1;
+ zero_dreg = gen_rtx (REG, HImode, 3);
+ }
+ }
+
+ /* Now see if we could load the value into a address register. */
+ if (zero_dreg == NULL_RTX
+ && areg_count > 2
+ && (!regs_ever_live[5] || !regs_ever_live[6]))
+ {
+ if (!regs_ever_live[5])
+ {
+ regs_ever_live[5] = 1;
+ zero_areg = gen_rtx (REG, HImode, 5);
+ }
+ if (!regs_ever_live[6])
+ {
+ regs_ever_live[6] = 1;
+ zero_areg = gen_rtx (REG, HImode, 6);
+ }
+ }
+
+ if (zero_dreg)
+ emit_move_insn (zero_dreg, const0_rtx);
+
+ if (zero_areg)
+ emit_move_insn (zero_areg, const0_rtx);
+
+ return;
+ }
+ }
+
+ out_of_line_epilogue = 0;
+
+ /* Temporarily stuff the static chain onto the stack so we can
+ use a0 as a scratch register during the prologue. */
+ if (current_function_needs_context)
+ {
+ emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (-4)));
+ emit_move_insn (gen_rtx (MEM, PSImode, stack_pointer_rtx),
+ gen_rtx (REG, PSImode, STATIC_CHAIN_REGNUM));
+ }
+
+ if (frame_pointer_needed)
+ {
+ /* Store a2 into a0 temporarily. */
+ emit_move_insn (gen_rtx (REG, PSImode, 4), frame_pointer_rtx);
+
+ /* Set up the frame pointer. */
+ emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
+ }
+
+ /* Make any necessary space for the saved registers and local frame. */
+ if (size)
+ emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (-size)));
+
+ /* Save the callee saved registers. They're saved into the top
+ of the frame, using the stack pointer. */
+ for (i = 0, offset = outgoing_args_size;
+ i < FIRST_PSEUDO_REGISTER; i++)
+ {
+ if (regs_ever_live[i] && !call_used_regs[i] && ! fixed_regs[i]
+ || (i == FRAME_POINTER_REGNUM && frame_pointer_needed))
+ {
+ int regno;
+
+ /* If we're saving the frame pointer, then it will be found in
+ register 4 (a0). */
+ regno = (i == FRAME_POINTER_REGNUM && frame_pointer_needed) ? 4 : i;
+
+ emit_move_insn (gen_rtx (MEM, PSImode,
+ gen_rtx (PLUS, Pmode,
+ stack_pointer_rtx,
+ GEN_INT (offset))),
+ gen_rtx (REG, PSImode, regno));
+ offset += 4;
+ }
+ }
+
+ /* Now put the static chain back where the rest of the function
+ expects to find it. */
+ if (current_function_needs_context)
+ {
+ emit_move_insn (gen_rtx (REG, PSImode, STATIC_CHAIN_REGNUM),
+ gen_rtx (MEM, PSImode,
+ gen_rtx (PLUS, PSImode, stack_pointer_rtx,
+ GEN_INT (size))));
+ }
+}
+
+/* Expand the epilogue into RTL. */
+void
+expand_epilogue ()
+{
+ unsigned int size;
+ unsigned int outgoing_args_size = current_function_outgoing_args_size;
+ int offset, i, temp_regno;
+ rtx basereg;
+
+ size = total_frame_size ();
+
+ if (DECL_RESULT (current_function_decl)
+ && DECL_RTL (DECL_RESULT (current_function_decl))
+ && REG_P (DECL_RTL (DECL_RESULT (current_function_decl))))
+ temp_regno = (REGNO (DECL_RTL (DECL_RESULT (current_function_decl))) == 4
+ ? 0 : 4);
+ else
+ temp_regno = 4;
+
+ /* Emit an out of line epilogue sequence if it's profitable to do so. */
+ if (out_of_line_epilogue)
+ {
+ /* If there were no outgoing arguments and no local frame, then
+ we will be able to omit the rts at the end of this function,
+ so just jump to the epilogue_noreturn routine. */
+ if (get_frame_size () == 0 && outgoing_args_size == 0)
+ {
+ emit_jump_insn (gen_outline_epilogue_jump ());
+ return;
+ }
+
+ if (outgoing_args_size)
+ emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (outgoing_args_size)));
+
+ if (temp_regno == 0)
+ emit_insn (gen_outline_epilogue_call_d0 ());
+ else if (temp_regno == 4)
+ emit_insn (gen_outline_epilogue_call_a0 ());
+
+ if (get_frame_size () != 0)
+ emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (size - outgoing_args_size - 16)));
+ emit_jump_insn (gen_return_internal ());
+ return;
+ }
+
+ /* Registers are restored from the frame pointer if we have one,
+ else they're restored from the stack pointer. Figure out
+ the appropriate offset to the register save area for both cases. */
+ if (frame_pointer_needed)
+ {
+ basereg = frame_pointer_rtx;
+ offset = -(size - outgoing_args_size);
+ }
+ else
+ {
+ basereg = stack_pointer_rtx;
+ offset = outgoing_args_size;
+ }
+
+ /* Restore each register. */
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ {
+ if (regs_ever_live[i] && !call_used_regs[i] && ! fixed_regs[i]
+ || (i == FRAME_POINTER_REGNUM && frame_pointer_needed))
+ {
+ int regno;
+
+ /* Restore the frame pointer (if it exists) into a temporary
+ register. */
+ regno = ((i == FRAME_POINTER_REGNUM && frame_pointer_needed)
+ ? temp_regno : i);
+
+ emit_move_insn (gen_rtx (REG, PSImode, regno),
+ gen_rtx (MEM, PSImode,
+ gen_rtx (PLUS, Pmode,
+ basereg,
+ GEN_INT (offset))));
+ offset += 4;
+ }
+ }
+
+ if (frame_pointer_needed)
+ {
+ /* Deallocate this frame's stack. */
+ emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+ /* Restore the old frame pointer. */
+ emit_move_insn (frame_pointer_rtx, gen_rtx (REG, PSImode, temp_regno));
+ }
+ else if (size)
+ {
+ /* Deallocate this function's stack. */
+ emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (size)));
+ }
+
+ /* If we had to allocate a slot to save the context pointer,
+ then it must be deallocated here. */
+ if (current_function_needs_context)
+ emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (4)));
+
+ /* Emit the return insn, if this function had no stack, then we
+ can use the standard return (which allows more optimizations),
+ else we have to use the special one which inhibits optimizations. */
+ if (size == 0 && !current_function_needs_context)
+ emit_jump_insn (gen_return ());
+ else
+ emit_jump_insn (gen_return_internal ());
+}
+
+/* Update the condition code from the insn. */
+
+void
+notice_update_cc (body, insn)
+ rtx body;
+ rtx insn;
+{
+ switch (get_attr_cc (insn))
+ {
+ case CC_NONE:
+ /* Insn does not affect CC at all. */
+ break;
+
+ case CC_NONE_0HIT:
+ /* Insn does not change CC, but the 0'th operand has been changed. */
+ if (cc_status.value1 != 0
+ && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
+ cc_status.value1 = 0;
+ break;
+
+ case CC_SET_ZN:
+ /* Insn sets the Z,N flags of CC to recog_operand[0].
+ V,C is in an unusable state. */
+ CC_STATUS_INIT;
+ cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
+ cc_status.value1 = recog_operand[0];
+ break;
+
+ case CC_SET_ZNV:
+ /* Insn sets the Z,N,V flags of CC to recog_operand[0].
+ C is in an unusable state. */
+ CC_STATUS_INIT;
+ cc_status.flags |= CC_NO_CARRY;
+ cc_status.value1 = recog_operand[0];
+ break;
+
+ case CC_COMPARE:
+ /* The insn is a compare instruction. */
+ CC_STATUS_INIT;
+ cc_status.value1 = SET_SRC (body);
+ break;
+
+ case CC_CLOBBER:
+ /* Insn doesn't leave CC in a usable state. */
+ CC_STATUS_INIT;
+ break;
+
+ default:
+ CC_STATUS_INIT;
+ break;
+ }
+}
+
+/* Return true if OP is a valid call operand. Valid call operands
+ are SYMBOL_REFs and REGs. */
+int
+call_address_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
+}
+
+/* Return true if OP is a memory operand with a constant address.
+ A special PSImode move pattern uses this predicate. */
+int
+constant_memory_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ return GET_CODE (op) == MEM && CONSTANT_ADDRESS_P (XEXP (op, 0));
+}
+
+/* What (if any) secondary registers are needed to move IN with mode
+ MODE into a register from in register class CLASS.
+
+ We might be able to simplify this. */
+enum reg_class
+secondary_reload_class (class, mode, in, input)
+ enum reg_class class;
+ enum machine_mode mode;
+ rtx in;
+ int input;
+{
+ int regno;
+
+ /* Memory loads less than a full word wide can't have an
+ address or stack pointer destination. They must use
+ a data register as an intermediate register. */
+ if (input
+ && GET_CODE (in) == MEM
+ && (mode == QImode)
+ && class == ADDRESS_REGS)
+ return DATA_REGS;
+
+ /* Address register stores which are not PSImode need a scratch register. */
+ if (! input
+ && GET_CODE (in) == MEM
+ && (mode != PSImode)
+ && class == ADDRESS_REGS)
+ return DATA_REGS;
+
+ /* Otherwise assume no secondary reloads are needed. */
+ return NO_REGS;
+}
+
+
+/* Shifts.
+
+ We devote a fair bit of code to getting efficient shifts since we can only
+ shift one bit at a time, and each single bit shift may take multiple
+ instructions.
+
+ The basic shift methods:
+
+ * loop shifts -- emit a loop using one (or two on H8/S) bit shifts;
+ this is the default. SHIFT_LOOP
+
+ * inlined shifts -- emit straight line code for the shift; this is
+ used when a straight line shift is about the same size or smaller
+ than a loop. We allow the inline version to be slightly longer in
+ some cases as it saves a register. SHIFT_INLINE
+
+ * There other oddballs. Not worth explaining. SHIFT_SPECIAL
+
+
+ HImode shifts:
+
+ 1-4 do them inline
+
+ 5-7 If ashift, then multiply, else loop.
+
+ 8-14 - If ashift, then multiply, if lshiftrt, then divide, else loop.
+ 15 - rotate the bit we want into the carry, clear the destination,
+ (use mov 0,dst, not sub as sub will clobber the carry), then
+ move bit into place.
+
+ Don't Panic, it's not nearly as bad as the H8 shifting code!!! */
+
+int
+nshift_operator (x, mode)
+ rtx x;
+ enum machine_mode mode;
+{
+ switch (GET_CODE (x))
+ {
+ case ASHIFTRT:
+ case LSHIFTRT:
+ case ASHIFT:
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+/* Called from the .md file to emit code to do shifts.
+ Returns a boolean indicating success
+ (currently this is always TRUE). */
+
+int
+expand_a_shift (mode, code, operands)
+ enum machine_mode mode;
+ int code;
+ rtx operands[];
+{
+ emit_move_insn (operands[0], operands[1]);
+
+ /* need a loop to get all the bits we want - we generate the
+ code at emit time, but need to allocate a scratch reg now */
+
+ emit_insn (gen_rtx
+ (PARALLEL, VOIDmode,
+ gen_rtvec (2,
+ gen_rtx (SET, VOIDmode, operands[0],
+ gen_rtx (code, mode,
+ operands[0], operands[2])),
+ gen_rtx (CLOBBER, VOIDmode,
+ gen_rtx (SCRATCH, HImode, 0)))));
+
+ return 1;
+}
+
+/* Shift algorithm determination.
+
+ There are various ways of doing a shift:
+ SHIFT_INLINE: If the amount is small enough, just generate as many one-bit
+ shifts as we need.
+ SHIFT_SPECIAL: Hand crafted assembler.
+ SHIFT_LOOP: If the above methods fail, just loop. */
+
+enum shift_alg
+{
+ SHIFT_INLINE,
+ SHIFT_SPECIAL,
+ SHIFT_LOOP,
+ SHIFT_MAX
+};
+
+/* Symbols of the various shifts which can be used as indices. */
+
+enum shift_type
+ {
+ SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
+ };
+
+/* Symbols of the various modes which can be used as indices. */
+
+enum shift_mode
+ {
+ HIshift,
+ };
+
+/* For single bit shift insns, record assembler and what bits of the
+ condition code are valid afterwards (represented as various CC_FOO
+ bits, 0 means CC isn't left in a usable state). */
+
+struct shift_insn
+{
+ char *assembler;
+ int cc_valid;
+};
+
+/* Assembler instruction shift table.
+
+ These tables are used to look up the basic shifts.
+ They are indexed by cpu, shift_type, and mode.
+*/
+
+static const struct shift_insn shift_one[3][3] =
+{
+ {
+/* SHIFT_ASHIFT */
+ { "add\t%0,%0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
+ },
+/* SHIFT_LSHIFTRT */
+ {
+ { "lsr\t%0", CC_NO_CARRY },
+ },
+/* SHIFT_ASHIFTRT */
+ {
+ { "asr\t%0", CC_NO_CARRY },
+ },
+};
+
+/* Given CPU, MODE, SHIFT_TYPE, and shift count COUNT, determine the best
+ algorithm for doing the shift. The assembler code is stored in ASSEMBLER.
+ We don't achieve maximum efficiency in all cases, but the hooks are here
+ to do so.
+
+ For now we just use lots of switch statements. Since we don't even come
+ close to supporting all the cases, this is simplest. If this function ever
+ gets too big, perhaps resort to a more table based lookup. Of course,
+ at this point you may just wish to do it all in rtl. */
+
+static enum shift_alg
+get_shift_alg (shift_type, mode, count, assembler_p, cc_valid_p)
+ enum shift_type shift_type;
+ enum machine_mode mode;
+ int count;
+ const char **assembler_p;
+ int *cc_valid_p;
+{
+ /* The default is to loop. */
+ enum shift_alg alg = SHIFT_LOOP;
+ enum shift_mode shift_mode;
+
+ /* We don't handle negative shifts or shifts greater than the word size,
+ they should have been handled already. */
+
+ if (count < 0 || count > GET_MODE_BITSIZE (mode))
+ abort ();
+
+ switch (mode)
+ {
+ case HImode:
+ shift_mode = HIshift;
+ break;
+ default:
+ abort ();
+ }
+
+ /* Assume either SHIFT_LOOP or SHIFT_INLINE.
+ It is up to the caller to know that looping clobbers cc. */
+ *assembler_p = shift_one[shift_type][shift_mode].assembler;
+ *cc_valid_p = shift_one[shift_type][shift_mode].cc_valid;
+
+ /* Now look for cases we want to optimize. */
+
+ switch (shift_mode)
+ {
+ case HIshift:
+ if (count <= 4)
+ return SHIFT_INLINE;
+ else if (count < 15 && shift_type != SHIFT_ASHIFTRT)
+ {
+ switch (count)
+ {
+ case 5:
+ if (shift_type == SHIFT_ASHIFT)
+ *assembler_p = "mov 32,%4\n\tmul %4,%0";
+ else if (shift_type == SHIFT_LSHIFTRT)
+ *assembler_p
+ = "sub %4,%4\n\tmov %4,mdr\n\tmov 32,%4\n\tdivu %4,%0";
+ *cc_valid_p = CC_NO_CARRY;
+ return SHIFT_SPECIAL;
+ case 6:
+ if (shift_type == SHIFT_ASHIFT)
+ *assembler_p = "mov 64,%4\n\tmul %4,%0";
+ else if (shift_type == SHIFT_LSHIFTRT)
+ *assembler_p
+ = "sub %4,%4\n\tmov %4,mdr\n\tmov 64,%4\n\tdivu %4,%0";
+ *cc_valid_p = CC_NO_CARRY;
+ return SHIFT_SPECIAL;
+ case 7:
+ if (shift_type == SHIFT_ASHIFT)
+ *assembler_p = "mov 128,%4\n\tmul %4,%0";
+ else if (shift_type == SHIFT_LSHIFTRT)
+ *assembler_p
+ = "sub %4,%4\n\tmov %4,mdr\n\tmov 128,%4\n\tdivu %4,%0";
+ *cc_valid_p = CC_NO_CARRY;
+ return SHIFT_SPECIAL;
+ case 8:
+ if (shift_type == SHIFT_ASHIFT)
+ *assembler_p = "mov 256,%4\n\tmul %4,%0";
+ else if (shift_type == SHIFT_LSHIFTRT)
+ *assembler_p
+ = "sub %4,%4\n\tmov %4,mdr\n\tmov 256,%4\n\tdivu %4,%0";
+ *cc_valid_p = CC_NO_CARRY;
+ return SHIFT_SPECIAL;
+ case 9:
+ if (shift_type == SHIFT_ASHIFT)
+ *assembler_p = "mov 512,%4\n\tmul %4,%0";
+ else if (shift_type == SHIFT_LSHIFTRT)
+ *assembler_p
+ = "sub %4,%4\n\tmov %4,mdr\n\tmov 512,%4\n\tdivu %4,%0";
+ *cc_valid_p = CC_NO_CARRY;
+ return SHIFT_SPECIAL;
+ case 10:
+ if (shift_type == SHIFT_ASHIFT)
+ *assembler_p = "mov 1024,%4\n\tmul %4,%0";
+ else if (shift_type == SHIFT_LSHIFTRT)
+ *assembler_p
+ = "sub %4,%4\n\tmov %4,mdr\n\tmov 1024,%4\n\tdivu %4,%0";
+ *cc_valid_p = CC_NO_CARRY;
+ return SHIFT_SPECIAL;
+ case 11:
+ if (shift_type == SHIFT_ASHIFT)
+ *assembler_p = "mov 2048,%4\n\tmul %4,%0";
+ else if (shift_type == SHIFT_LSHIFTRT)
+ *assembler_p
+ = "sub %4,%4\n\tmov %4,mdr\n\tmov 2048,%4\n\tdivu %4,%0";
+ *cc_valid_p = CC_NO_CARRY;
+ return SHIFT_SPECIAL;
+ case 12:
+ if (shift_type == SHIFT_ASHIFT)
+ *assembler_p = "mov 4096,%4\n\tmul %4,%0";
+ else if (shift_type == SHIFT_LSHIFTRT)
+ *assembler_p
+ = "sub %4,%4\n\tmov %4,mdr\n\tmov 4096,%4\n\tdivu %4,%0";
+ *cc_valid_p = CC_NO_CARRY;
+ return SHIFT_SPECIAL;
+ case 13:
+ if (shift_type == SHIFT_ASHIFT)
+ *assembler_p = "mov 8192,%4\n\tmul %4,%0";
+ else if (shift_type == SHIFT_LSHIFTRT)
+ *assembler_p
+ = "sub %4,%4\n\tmov %4,mdr\n\tmov 8192,%4\n\tdivu %4,%0";
+ *cc_valid_p = CC_NO_CARRY;
+ return SHIFT_SPECIAL;
+ case 14:
+ if (shift_type == SHIFT_ASHIFT)
+ *assembler_p = "mov 16384,%4\n\tmul %4,%0";
+ else if (shift_type == SHIFT_LSHIFTRT)
+ *assembler_p
+ = "sub %4,%4\n\tmov %4,mdr\n\tmov 16384,%4\n\tdivu %4,%0";
+ *cc_valid_p = CC_NO_CARRY;
+ return SHIFT_SPECIAL;
+ }
+ }
+ else if (count == 15)
+ {
+ if (shift_type == SHIFT_ASHIFTRT)
+ {
+ *assembler_p = "add\t%0,%0\n\tsubc\t%0,%0\n";
+ *cc_valid_p = CC_NO_CARRY;
+ return SHIFT_SPECIAL;
+ }
+ if (shift_type == SHIFT_LSHIFTRT)
+ {
+ *assembler_p = "add\t%0,%0\n\tmov 0,%0\n\trol %0\n";
+ *cc_valid_p = CC_NO_CARRY;
+ return SHIFT_SPECIAL;
+ }
+ if (shift_type == SHIFT_ASHIFT)
+ {
+ *assembler_p = "ror\t%0\n\tmov 0,%0\n\tror %0\n";
+ *cc_valid_p = CC_NO_CARRY;
+ return SHIFT_SPECIAL;
+ }
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ return alg;
+}
+
+/* Emit the assembler code for doing shifts. */
+
+char *
+emit_a_shift (insn, operands)
+ rtx insn;
+ rtx *operands;
+{
+ static int loopend_lab;
+ char *assembler;
+ int cc_valid;
+ rtx inside = PATTERN (insn);
+ rtx shift = operands[3];
+ enum machine_mode mode = GET_MODE (shift);
+ enum rtx_code code = GET_CODE (shift);
+ enum shift_type shift_type;
+ enum shift_mode shift_mode;
+
+ loopend_lab++;
+
+ switch (mode)
+ {
+ case HImode:
+ shift_mode = HIshift;
+ break;
+ default:
+ abort ();
+ }
+
+ switch (code)
+ {
+ case ASHIFTRT:
+ shift_type = SHIFT_ASHIFTRT;
+ break;
+ case LSHIFTRT:
+ shift_type = SHIFT_LSHIFTRT;
+ break;
+ case ASHIFT:
+ shift_type = SHIFT_ASHIFT;
+ break;
+ default:
+ abort ();
+ }
+
+ if (GET_CODE (operands[2]) != CONST_INT)
+ {
+ /* Indexing by reg, so have to loop and test at top */
+ output_asm_insn ("mov %2,%4", operands);
+ output_asm_insn ("cmp 0,%4", operands);
+ fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
+
+ /* Get the assembler code to do one shift. */
+ get_shift_alg (shift_type, mode, 1, &assembler, &cc_valid);
+ }
+ else
+ {
+ int n = INTVAL (operands[2]);
+ enum shift_alg alg;
+
+ /* If the count is negative, make it 0. */
+ if (n < 0)
+ n = 0;
+ /* If the count is too big, truncate it.
+ ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
+ do the intuitive thing. */
+ else if (n > GET_MODE_BITSIZE (mode))
+ n = GET_MODE_BITSIZE (mode);
+
+ alg = get_shift_alg (shift_type, mode, n, &assembler, &cc_valid);
+
+
+ switch (alg)
+ {
+ case SHIFT_INLINE:
+ /* Emit one bit shifts. */
+ while (n > 0)
+ {
+ output_asm_insn (assembler, operands);
+ n -= 1;
+ }
+
+ /* Keep track of CC. */
+ if (cc_valid)
+ {
+ cc_status.value1 = operands[0];
+ cc_status.flags |= cc_valid;
+ }
+ return "";
+
+ case SHIFT_SPECIAL:
+ output_asm_insn (assembler, operands);
+
+ /* Keep track of CC. */
+ if (cc_valid)
+ {
+ cc_status.value1 = operands[0];
+ cc_status.flags |= cc_valid;
+ }
+ return "";
+ }
+
+ {
+ fprintf (asm_out_file, "\tmov %d,%s\n", n,
+ reg_names[REGNO (operands[4])]);
+ fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
+ output_asm_insn (assembler, operands);
+ output_asm_insn ("add -1,%4", operands);
+ fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
+ return "";
+ }
+ }
+
+ fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
+ output_asm_insn (assembler, operands);
+ output_asm_insn ("add -1,%4", operands);
+ fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
+ fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
+
+ return "";
+}
+
+/* Return an RTX to represent where a value with mode MODE will be returned
+ from a function. If the result is 0, the argument is pushed. */
+
+rtx
+function_arg (cum, mode, type, named)
+ CUMULATIVE_ARGS *cum;
+ enum machine_mode mode;
+ tree type;
+ int named;
+{
+ rtx result = 0;
+ int size, align;
+
+ /* We only support using 2 data registers as argument registers. */
+ int nregs = 2;
+
+ /* Only pass named arguments in registers. */
+ if (!named)
+ return NULL_RTX;
+
+ /* Figure out the size of the object to be passed. We lie and claim
+ PSImode values are only two bytes since they fit in a single
+ register. */
+ if (mode == BLKmode)
+ size = int_size_in_bytes (type);
+ else if (mode == PSImode)
+ size = 2;
+ else
+ size = GET_MODE_SIZE (mode);
+
+ /* Figure out the alignment of the object to be passed. */
+ align = size;
+
+ cum->nbytes = (cum->nbytes + 1) & ~1;
+
+ /* Don't pass this arg via a register if all the argument registers
+ are used up. */
+ if (cum->nbytes + size > nregs * UNITS_PER_WORD)
+ return 0;
+
+ switch (cum->nbytes / UNITS_PER_WORD)
+ {
+ case 0:
+ result = gen_rtx (REG, mode, 0);
+ break;
+ case 1:
+ result = gen_rtx (REG, mode, 1);
+ break;
+ default:
+ result = 0;
+ }
+
+ return result;
+}
+
+/* Return the number of registers to use for an argument passed partially
+ in registers and partially in memory. */
+
+int
+function_arg_partial_nregs (cum, mode, type, named)
+ CUMULATIVE_ARGS *cum;
+ enum machine_mode mode;
+ tree type;
+ int named;
+{
+ int size, align;
+
+ /* We only support using 2 data registers as argument registers. */
+ int nregs = 2;
+
+ return 0;
+ /* Only pass named arguments in registers. */
+ if (!named)
+ return 0;
+
+ /* Figure out the size of the object to be passed. */
+ if (mode == BLKmode)
+ size = int_size_in_bytes (type);
+ else if (mode == PSImode)
+ size = 2;
+ else
+ size = GET_MODE_SIZE (mode);
+
+ /* Figure out the alignment of the object to be passed. */
+ align = size;
+
+ cum->nbytes = (cum->nbytes + 1) & ~1;
+
+ /* Don't pass this arg via a register if all the argument registers
+ are used up. */
+ if (cum->nbytes > nregs * UNITS_PER_WORD)
+ return 0;
+
+ if (cum->nbytes + size <= nregs * UNITS_PER_WORD)
+ return 0;
+
+ /* Don't pass this arg via a register if it would be split between
+ registers and memory. */
+ if (type == NULL_TREE
+ && cum->nbytes + size > nregs * UNITS_PER_WORD)
+ return 0;
+
+ return (nregs * UNITS_PER_WORD - cum->nbytes) / UNITS_PER_WORD;
+}
+
+char *
+output_tst (operand, insn)
+ rtx operand, insn;
+{
+
+ rtx temp;
+ int past_call = 0;
+
+ /* Only tst insns using address registers can be optimized. */
+ if (REGNO_REG_CLASS (REGNO (operand)) != ADDRESS_REGS)
+ return "cmp 0,%0";
+
+ /* If testing an address register against zero, we can do better if
+ we know there's a register already holding the value zero. First
+ see if a global register has been set to zero, else we do a search
+ for a register holding zero, if both of those fail, then we use a
+ compare against zero. */
+ if (zero_dreg || zero_areg)
+ {
+ rtx xoperands[2];
+ xoperands[0] = operand;
+ xoperands[1] = zero_dreg ? zero_dreg : zero_areg;
+
+ output_asm_insn ("cmp %1,%0", xoperands);
+ return "";
+ }
+
+ /* We can save a byte if we can find a register which has the value
+ zero in it. */
+ temp = PREV_INSN (insn);
+ while (temp)
+ {
+ rtx set;
+
+ /* We allow the search to go through call insns. We record
+ the fact that we've past a CALL_INSN and reject matches which
+ use call clobbered registers. */
+ if (GET_CODE (temp) == CODE_LABEL
+ || GET_CODE (temp) == JUMP_INSN
+ || GET_CODE (temp) == BARRIER)
+ break;
+
+ if (GET_CODE (temp) == CALL_INSN)
+ past_call = 1;
+
+ if (GET_CODE (temp) == NOTE)
+ {
+ temp = PREV_INSN (temp);
+ continue;
+ }
+
+ /* It must be an insn, see if it is a simple set. */
+ set = single_set (temp);
+ if (!set)
+ {
+ temp = PREV_INSN (temp);
+ continue;
+ }
+
+ /* Are we setting a register to zero?
+
+ If it's a call clobbered register, have we past a call? */
+ if (REG_P (SET_DEST (set))
+ && SET_SRC (set) == CONST0_RTX (GET_MODE (SET_DEST (set)))
+ && !reg_set_between_p (SET_DEST (set), temp, insn)
+ && (!past_call
+ || !call_used_regs[REGNO (SET_DEST (set))]))
+ {
+ rtx xoperands[2];
+ xoperands[0] = operand;
+ xoperands[1] = SET_DEST (set);
+
+ output_asm_insn ("cmp %1,%0", xoperands);
+ return "";
+ }
+ temp = PREV_INSN (temp);
+ }
+ return "cmp 0,%0";
+}
+
+/* Return nonzero if OP is a valid operand for a {zero,sign}_extendpsisi
+ instruction.
+
+ It accepts anything that is a general operand or the sum of the
+ stack pointer and a general operand. */
+extendpsi_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ return (general_operand (op, mode)
+ || (GET_CODE (op) == PLUS
+ && XEXP (op, 0) == stack_pointer_rtx
+ && general_operand (XEXP (op, 1), VOIDmode)));
+}
diff --git a/gnu/usr.bin/gcc/config/mn10200/mn10200.h b/gnu/usr.bin/gcc/config/mn10200/mn10200.h
new file mode 100644
index 00000000000..7eb26dd7c0d
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10200/mn10200.h
@@ -0,0 +1,1078 @@
+/* Definitions of target machine for GNU compiler. Matsushita MN10200 series
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Jeff Law (law@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 "svr4.h"
+
+/* Get rid of svr4.h stuff we don't want/need. */
+#undef ASM_SPEC
+#undef ASM_FINAL_SPEC
+#undef LIB_SPEC
+#undef ENDFILE_SPEC
+#undef LINK_SPEC
+#undef STARTFILE_SPEC
+
+/* Names to predefine in the preprocessor for this target machine. */
+
+#define CPP_PREDEFINES "-D__mn10200__ -D__MN10200__ -D__LONG_MAX__=2147483647L -D__LONG_LONG_MAX__=2147483647L -D__INT_MAX__=32767"
+
+/* Run-time compilation parameters selecting different hardware subsets. */
+
+/* We don't have any switched on the mn10200. Though there are some things
+ that might be worth a switch:
+
+ -mspace to optimize even more for space.
+
+ -mrelax to enable the relaxing linker. */
+
+extern int target_flags;
+
+/* Macros used in the machine description to test the flags. */
+
+/* Macro to define tables used to set the flags.
+ This is a list in braces of pairs in braces,
+ each pair being { "NAME", VALUE }
+ where VALUE is the bits to set or minus the bits to clear.
+ An empty string NAME is used to identify the default VALUE. */
+
+#define TARGET_SWITCHES \
+ {{ "", TARGET_DEFAULT}}
+
+#ifndef TARGET_DEFAULT
+#define TARGET_DEFAULT 0
+#endif
+
+/* Print subsidiary information on the compiler version in use. */
+
+#define TARGET_VERSION fprintf (stderr, " (MN10200)");
+
+
+/* Target machine storage layout */
+
+/* Define this if most significant bit is lowest numbered
+ in instructions that operate on numbered bit-fields.
+ This is not true on the Matsushita MN10300. */
+#define BITS_BIG_ENDIAN 0
+
+/* Define this if most significant byte of a word is the lowest numbered. */
+/* This is not true on the Matsushita MN10200. */
+#define BYTES_BIG_ENDIAN 0
+
+/* Define this if most significant word of a multiword number is lowest
+ numbered.
+ This is not true on the Matsushita MN10200. */
+#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 68000, this would still be 32.
+ But on a machine with 16-bit registers, this would be 16.
+
+ This is a white lie. Registers are really 24bits, but most operations
+ only operate on 16 bits. GCC chokes badly if we set this to a value
+ that is not a power of two. */
+#define BITS_PER_WORD 16
+
+/* Width of a word, in units (bytes). */
+#define UNITS_PER_WORD 2
+
+/* Width in bits of a pointer.
+ See also the macro `Pmode' defined below.
+
+ This differs from Pmode because we need to allocate 32bits of space
+ to hold the 24bit pointers on this machine. */
+#define POINTER_SIZE 32
+
+/* Allocation boundary (in *bits*) for storing arguments in argument list. */
+#define PARM_BOUNDARY 16
+
+/* The stack goes in 16 bit lumps. */
+#define STACK_BOUNDARY 16
+
+/* Allocation boundary (in *bits*) for the code of a function.
+ 8 is the minimum boundary; it's unclear if bigger alignments
+ would improve performance. */
+#define FUNCTION_BOUNDARY 8
+
+/* No data type wants to be aligned rounder than this. */
+#define BIGGEST_ALIGNMENT 16
+
+/* Alignment of field after `int : 0' in a structure. */
+#define EMPTY_FIELD_BOUNDARY 16
+
+/* Seems to be how the Matsushita compiler does things, and there's
+ no real reason to be different. */
+#define STRUCTURE_SIZE_BOUNDARY 16
+#undef PCC_BITFIELD_TYPE_MATTERS
+
+/* Define this if move instructions will actually fail to work
+ when given unaligned data. */
+#define STRICT_ALIGNMENT 1
+
+/* Define this as 1 if `char' should by default be signed; else as 0. */
+#define DEFAULT_SIGNED_CHAR 0
+
+/* 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
+
+/* Standard register usage. */
+
+/* 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.
+
+ XXX Long term we should probably expose the MDR register, we use
+ it for division, multiplication, and some extension operations. */
+
+#define FIRST_PSEUDO_REGISTER 8
+
+/* 1 for registers that have pervasive standard uses
+ and are not available for the register allocator. */
+
+#define FIXED_REGISTERS \
+ { 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 \
+ { 1, 1, 0, 0, 1, 0, 0, 1}
+
+#define REG_ALLOC_ORDER \
+ { 0, 1, 4, 2, 3, 5, 6, 7}
+
+/* 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. */
+
+#define HARD_REGNO_NREGS(REGNO, MODE) \
+ ((MODE) == PSImode ? 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.
+
+ We allow any register to hold a PSImode value. We allow any register
+ to hold values <= 16 bits. For values > 16 bits we require aligned
+ register pairs. */
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+ ((MODE) == PSImode ? 1 : ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) <= 2)
+
+/* 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 || (GET_MODE_SIZE (MODE1) <= 2 && GET_MODE_SIZE (MODE2) <= 2))
+
+/* 4 data, and effectively 2 address registers is small as far as I'm
+ concerned. Especially since we use 2 data registers for argument
+ passing and return values.
+
+ We used to define CLASS_LIKELY_SPILLED_P as true for DATA_REGS too,
+ but we've made improvements to the port which greatly reduce register
+ pressure. As a result we no longer need to define CLASS_LIKELY_SPILLED_P
+ for DATA_REGS (and by not defining it we get significantly better code). */
+#define SMALL_REGISTER_CLASSES 1
+#define CLASS_LIKELY_SPILLED_P(CLASS) (CLASS == ADDRESS_REGS)
+
+/* 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. */
+
+enum reg_class {
+ NO_REGS, DATA_REGS, ADDRESS_REGS, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
+};
+
+#define N_REG_CLASSES (int) LIM_REG_CLASSES
+
+/* Give names of register classes as strings for dump file. */
+
+#define REG_CLASS_NAMES \
+{ "NO_REGS", "DATA_REGS", "ADDRESS_REGS", \
+ "GENERAL_REGS", "ALL_REGS", "LIM_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, /* No regs */ \
+ 0x0f, /* DATA_REGS */ \
+ 0xf0, /* ADDRESS_REGS */ \
+ 0xff, /* GENERAL_REGS */ \
+ 0xff, /* ALL_REGS */ \
+}
+
+/* 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) \
+ ((REGNO) < 4 ? DATA_REGS : ADDRESS_REGS)
+
+/* The class value for index registers, and the one for base regs. */
+
+#define INDEX_REG_CLASS DATA_REGS
+#define BASE_REG_CLASS ADDRESS_REGS
+
+/* Get reg_class from a letter such as appears in the machine description. */
+
+#define REG_CLASS_FROM_LETTER(C) \
+ ((C) == 'd' ? DATA_REGS : \
+ (C) == 'a' ? ADDRESS_REGS : NO_REGS)
+
+/* 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_BASE_P(regno) \
+ (((regno) > 3 && regno < FIRST_PSEUDO_REGISTER) \
+ || (reg_renumber[regno] > 3 && reg_renumber[regno] < FIRST_PSEUDO_REGISTER))
+
+#define REGNO_OK_FOR_INDEX_P(regno) \
+ (((regno) >= 0 && regno < 4) \
+ || (reg_renumber[regno] >= 0 && reg_renumber[regno] < 4))
+
+
+/* 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. */
+
+#define PREFERRED_RELOAD_CLASS(X,CLASS) \
+ ((GET_MODE (X) != PSImode) ? DATA_REGS : CLASS)
+
+/* We want to use DATA_REGS for anything that is not PSImode. */
+#define LIMIT_RELOAD_CLASS(MODE, CLASS) \
+ ((MODE != PSImode) ? DATA_REGS : CLASS)
+
+/* We have/need secondary reloads on the mn10200. Mostly to deal
+ with problems using address registers. */
+#define SECONDARY_INPUT_RELOAD_CLASS(CLASS,MODE,IN) \
+ secondary_reload_class(CLASS,MODE,IN, 1)
+
+#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,IN) \
+ secondary_reload_class(CLASS,MODE,IN, 0)
+
+/* Return the maximum number of consecutive registers
+ needed to represent mode MODE in a register of class CLASS. */
+
+#define CLASS_MAX_NREGS(CLASS, MODE) \
+ ((MODE) == PSImode ? 1 : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* The letters I, J, K, L, M, N, O, P 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. */
+
+#define INT_8_BITS(VALUE) ((unsigned) (VALUE) + 0x80 < 0x100)
+#define INT_16_BITS(VALUE) ((unsigned) (VALUE) + 0x8000 < 0x10000)
+
+#define CONST_OK_FOR_I(VALUE) ((VALUE) == 0)
+#define CONST_OK_FOR_J(VALUE) ((VALUE) >= 1 && (VALUE) <= 3)
+#define CONST_OK_FOR_K(VALUE) ((VALUE) >= 1 && (VALUE) <= 4)
+#define CONST_OK_FOR_L(VALUE) ((VALUE) == 15)
+#define CONST_OK_FOR_M(VALUE) ((VALUE) == 255)
+
+#define CONST_OK_FOR_LETTER_P(VALUE, C) \
+ ((C) == 'I' ? CONST_OK_FOR_I (VALUE) : \
+ (C) == 'J' ? CONST_OK_FOR_J (VALUE) : \
+ (C) == 'K' ? CONST_OK_FOR_K (VALUE) : \
+ (C) == 'L' ? CONST_OK_FOR_L (VALUE) : \
+ (C) == 'M' ? CONST_OK_FOR_M (VALUE) : 0)
+
+/* Similar, but for floating constants, and defining letters G and H.
+ Here VALUE is the CONST_DOUBLE rtx itself.
+
+ `G' is a floating-point zero. */
+
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
+ ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
+ && (VALUE) == CONST0_RTX (GET_MODE (VALUE))) \
+ : 0)
+
+
+
+/* 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
+
+/* Offset of first parameter from the argument pointer register value. */
+/* Is equal to the size of the saved fp + pc, even if an fp isn't
+ saved since the value is used before we know. */
+
+#define FIRST_PARM_OFFSET(FNDECL) (current_function_needs_context ? 8 : 4)
+
+/* Specify the registers used for certain standard purposes.
+ The values of these macros are register numbers. */
+
+/* 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
+
+/* Base register for access to arguments of the function. */
+#define ARG_POINTER_REGNUM 6
+
+/* Register in which static-chain is passed to a function. */
+#define STATIC_CHAIN_REGNUM 4
+
+/* 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.
+
+ We allow frame pointers to be eliminated when not having one will
+ not interfere with debugging. */
+#define ACCUMULATE_OUTGOING_ARGS
+#define FRAME_POINTER_REQUIRED 0
+#define CAN_DEBUG_WITHOUT_FP
+
+/* Store in the variable DEPTH the initial difference between the
+ frame pointer reg contents and the stack pointer reg contents,
+ as of the start of the function body. This depends on the layout
+ of the fixed parts of the stack frame and on how registers are saved. */
+
+#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = total_frame_size()
+
+/* Various type size information.
+
+ The mn10200 has a limited number of small registers. Sizes of basic
+ data types are adjusted accordingly. */
+#define SHORT_TYPE_SIZE 16
+#define INT_TYPE_SIZE 16
+#define LONG_TYPE_SIZE 32
+#define LONG_LONG_TYPE_SIZE 32
+#define FLOAT_TYPE_SIZE 32
+#define DOUBLE_TYPE_SIZE 32
+#define LONG_DOUBLE_TYPE_SIZE DOUBLE_TYPE_SIZE
+
+/* Any size less than 64bits will work; but a smarter definition
+ can make G++ code smaller and faster. Most operations on the
+ mn10200 occur on 16bit hunks, so the best size for a boolean
+ is 16bits. */
+#define BOOL_TYPE_SIZE 16
+
+/* The difference of two pointers must be at least 24bits since pointers
+ are 24bits; however, no basic data type is 24bits, so we have to round
+ up to a 32bits for the difference of pointers. */
+#undef SIZE_TYPE
+#undef PTRDIFF_TYPE
+#define SIZE_TYPE "long unsigned int"
+#define PTRDIFF_TYPE "long unsigned int"
+
+/* Note sizeof (WCHAR_TYPE) must be equal to the value of WCHAR_TYPE_SIZE! */
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+#define MAX_FIXED_MODE_SIZE 32
+
+/* A guess for the MN10200. */
+#define PROMOTE_PROTOTYPES 1
+
+/* Value is the number of bytes of arguments automatically
+ popped when returning from a subroutine call.
+ FUNDECL is the declaration node of the function (as a tree),
+ FUNTYPE is the data type of the function (as a tree),
+ or for a library call it is an identifier node for the subroutine name.
+ SIZE is the number of bytes of arguments passed on the stack. */
+
+#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
+
+/* 1 if N is a possible register number for function argument passing. */
+
+#define FUNCTION_ARG_REGNO_P(N) ((N) <= 1)
+
+/* 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. */
+
+#define CUMULATIVE_ARGS struct cum_arg
+struct cum_arg { int nbytes; };
+
+/* 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.
+
+ On the MN10200, the offset starts at 0. */
+
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
+ ((CUM).nbytes = 0)
+
+/* 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) \
+ ((CUM).nbytes += ((MODE) != BLKmode \
+ ? (MODE) == PSImode ? 2 : \
+ (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD \
+ : (int_size_in_bytes (TYPE) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD))
+
+/* 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). */
+
+extern struct rtx_def *function_arg();
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
+ function_arg (&CUM, MODE, TYPE, NAMED)
+
+
+/* For "large" items, we pass them by invisible reference, and the
+ callee is responsible for copying the data item if it might be
+ modified. */
+#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
+ ((TYPE) && int_size_in_bytes (TYPE) > 8)
+
+#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
+ ((TYPE) && int_size_in_bytes (TYPE) > 8)
+
+/* 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), TYPE_MODE (VALTYPE) == PSImode ? 4 : 0)
+
+/* 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, (MODE) == PSImode ? 4 : 0)
+
+/* 1 if N is a possible register number for a function value. */
+
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0 || (N) == 4)
+
+/* Return values > 8 bytes in length in memory. */
+#define DEFAULT_PCC_STRUCT_RETURN 0
+#define RETURN_IN_MEMORY(TYPE) \
+ (int_size_in_bytes (TYPE) > 8 || TYPE_MODE (TYPE) == BLKmode)
+
+/* Register in which address to store a structure value
+ is passed to a function. On the MN10200 it's passed as
+ the first parameter. */
+
+#define STRUCT_VALUE 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. */
+
+#define EXIT_IGNORE_STACK 1
+
+/* Output assembler code to FILE to increment profiler label # LABELNO
+ for profiling a function entry.
+
+ ?!? Profiling is not currently supported. */
+
+#define FUNCTION_PROFILER(FILE, LABELNO) ;
+
+/* Yes, we actually support trampolines on this machine, even though
+ nobody is likely to ever use them. */
+#define TRAMPOLINE_TEMPLATE(FILE) \
+ do { \
+ fprintf (FILE, "\t.byte 0xfd\n"); \
+ fprintf (FILE, "\t.byte 0x00\n"); \
+ fprintf (FILE, "\t.byte 0x00\n"); \
+ fprintf (FILE, "\tmov (a3),a0\n"); \
+ fprintf (FILE, "\tadd -4,a3\n"); \
+ fprintf (FILE, "\tmov a0,(0,a3)\n"); \
+ fprintf (FILE, "\tmov (21,a0),a0\n"); \
+ fprintf (FILE, "\tmov a0,(4,a3)\n"); \
+ fprintf (FILE, "\tmov (0,a3),a0\n"); \
+ fprintf (FILE, "\tmov (17,a0),a0\n"); \
+ fprintf (FILE, "\tadd 4,a3\n"); \
+ fprintf (FILE, "\trts\n"); \
+ fprintf (FILE, "\t.long 0\n"); \
+ fprintf (FILE, "\t.long 0\n"); \
+ } while (0)
+
+/* Length in units of the trampoline for entering a nested function. */
+
+#define TRAMPOLINE_SIZE 0x1c
+
+/* 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, PSImode, plus_constant ((TRAMP), 20)), \
+ (CXT)); \
+ emit_move_insn (gen_rtx (MEM, PSImode, plus_constant ((TRAMP), 24)), \
+ (FNADDR)); \
+}
+
+/* A C expression whose value is RTL representing the value of the return
+ address for the frame COUNT steps up from the current frame. */
+
+#define RETURN_ADDR_RTX(COUNT, FRAME) \
+ ((COUNT == 0) \
+ ? gen_rtx (MEM, Pmode, frame_pointer_rtx) \
+ : (rtx) 0)
+
+
+/* Addressing modes, and classification of registers for them. */
+
+
+/* 1 if X is an rtx for a constant that is a valid address. */
+
+#define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)
+
+/* Extra constraints. */
+#define OK_FOR_R(OP) \
+ (GET_CODE (OP) == MEM \
+ && GET_MODE (OP) == QImode \
+ && REG_P (XEXP (OP, 0)))
+
+/* Q is used for sp + <something> in the {zero,sign}_extendpsisi2 patterns. */
+#define EXTRA_CONSTRAINT(OP, C) \
+ ((C) == 'R' ? OK_FOR_R (OP) : \
+ (C) == 'S' ? GET_CODE (OP) == SYMBOL_REF : \
+ (C) == 'Q' ? GET_CODE (OP) == PLUS : 0)
+
+/* Maximum number of registers that can appear in a valid memory address. */
+
+#define MAX_REGS_PER_ADDRESS 2
+
+/* 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. */
+
+#ifndef REG_OK_STRICT
+/* Nonzero if X is a hard reg that can be used as an index
+ or if it is a pseudo reg. */
+#define REG_OK_FOR_INDEX_P(X) \
+ (GET_MODE (X) == PSImode \
+ && ((REGNO (X) >= 0 && REGNO(X) <= 3) || REGNO (X) >= FIRST_PSEUDO_REGISTER))
+/* Nonzero if X is a hard reg that can be used as a base reg
+ or if it is a pseudo reg. */
+#define REG_OK_FOR_BASE_P(X) \
+ (GET_MODE (X) == PSImode \
+ && ((REGNO (X) >= 4 && REGNO(X) <= 8) || REGNO (X) >= FIRST_PSEUDO_REGISTER))
+#else
+/* Nonzero if X is a hard reg that can be used as an index. */
+#define REG_OK_FOR_INDEX_P(X) \
+ (GET_MODE (X) == PSImode) && REGNO_OK_FOR_INDEX_P (REGNO (X))
+/* Nonzero if X is a hard reg that can be used as a base reg. */
+#define REG_OK_FOR_BASE_P(X) \
+ (GET_MODE (X) == PSImode) && REGNO_OK_FOR_BASE_P (REGNO (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.
+
+ We used to allow reg+reg addresses for QImode and HImode; however,
+ they tended to cause the register allocator to run out of registers.
+ Basically, an indexed load/store always keeps 2 data and one address
+ register live, which is just too many for this machine.
+
+ The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS,
+ except for CONSTANT_ADDRESS_P which is actually machine-independent. */
+
+/* Accept either REG or SUBREG where a register is valid. */
+
+#define RTX_OK_FOR_BASE_P(X) \
+ ((REG_P (X) && REG_OK_FOR_BASE_P (X)) \
+ || (GET_CODE (X) == SUBREG && REG_P (SUBREG_REG (X)) \
+ && REG_OK_FOR_BASE_P (SUBREG_REG (X))))
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+{ \
+ if ((MODE != PSImode) && CONSTANT_ADDRESS_P (X)) \
+ goto ADDR; \
+ if (RTX_OK_FOR_BASE_P (X)) \
+ goto ADDR; \
+ if (GET_CODE (X) == PLUS) \
+ { \
+ rtx base = 0, index = 0; \
+ if (REG_P (XEXP (X, 0)) \
+ && REG_OK_FOR_BASE_P (XEXP (X, 0))) \
+ base = XEXP (X, 0), index = XEXP (X, 1); \
+ if (REG_P (XEXP (X, 1)) \
+ && REG_OK_FOR_BASE_P (XEXP (X, 1))) \
+ base = XEXP (X, 1), index = XEXP (X, 0); \
+ if (base != 0 && index != 0) \
+ { \
+ if (GET_CODE (index) == CONST_INT) \
+ goto ADDR; \
+ } \
+ } \
+}
+
+
+/* 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. */
+
+#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) {}
+
+/* Go to LABEL if ADDR (a legitimate address expression)
+ has an effect that depends on the machine mode it is used for. */
+
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) {}
+
+/* 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
+
+
+/* Tell final.c how to eliminate redundant test instructions. */
+
+/* Here we define machine-dependent flags and fields in cc_status
+ (see `conditions.h'). No extra ones are needed for the vax. */
+
+/* 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 CC_OVERFLOW_UNUSABLE 0x200
+#define CC_NO_CARRY CC_NO_OVERFLOW
+#define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc(EXP, INSN)
+
+/* The mn10200 has a limited number of registers, so CSE of function
+ addresses generally makes code worse due to register pressure. */
+#define NO_FUNCTION_CSE
+
+/* 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: \
+ /* Zeros are extremely cheap. */ \
+ if (INTVAL (RTX) == 0) \
+ return 0; \
+ /* If it fits in 8 bits, then it's still relatively cheap. */ \
+ if (INT_8_BITS (INTVAL (RTX))) \
+ return 1; \
+ /* This is the "base" cost, includes constants where either the \
+ upper or lower 16bits are all zeros. */ \
+ if (INT_16_BITS (INTVAL (RTX)) \
+ || (INTVAL (RTX) & 0xffff) == 0 \
+ || (INTVAL (RTX) & 0xffff0000) == 0) \
+ return 2; \
+ return 4; \
+ /* These are more costly than a CONST_INT, but we can relax them, \
+ so they're less costly than a CONST_DOUBLE. */ \
+ case CONST: \
+ case LABEL_REF: \
+ case SYMBOL_REF: \
+ return 6; \
+ /* We don't optimize CONST_DOUBLEs well nor do we relax them well, \
+ so their cost is very high. */ \
+ case CONST_DOUBLE: \
+ return 8;
+
+/* Make moves between different classes more expensive than moves
+ within the same class. */
+#define REGISTER_MOVE_COST(CLASS1, CLASS2) (CLASS1 != CLASS2 ? 4 : 2)
+
+/* Provide the costs of a rtl expression. This is in the body of a
+ switch on CODE.
+
+ ?!? This probably needs more work. The definitions below were first
+ taken from the H8 port, then tweaked slightly to improve code density
+ on various sample codes. */
+
+#define RTX_COSTS(RTX,CODE,OUTER_CODE) \
+ case MOD: \
+ case DIV: \
+ return 8; \
+ case MULT: \
+ return (GET_MODE (RTX) == SImode ? 20 : 8);
+
+/* Nonzero if access to memory by bytes or half words is no faster
+ than accessing full words. */
+#define SLOW_BYTE_ACCESS 1
+
+/* According expr.c, a value of around 6 should minimize code size, and
+ for the MN10200 series, code size our primary concern. */
+#define MOVE_RATIO 6
+
+#define TEXT_SECTION_ASM_OP "\t.section .text"
+#define DATA_SECTION_ASM_OP "\t.section .data"
+#define BSS_SECTION_ASM_OP "\t.section .bss"
+
+/* Output at beginning/end of assembler file. */
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) asm_file_start(FILE)
+
+#define ASM_COMMENT_START "#"
+
+/* 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"
+
+/* This is how to output an assembler line defining a `double' constant.
+ It is .dfloat or .gfloat, depending. */
+
+#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
+do { char dstr[30]; \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", dstr); \
+ fprintf (FILE, "\t.double %s\n", dstr); \
+ } while (0)
+
+
+/* This is how to output an assembler line defining a `float' constant. */
+#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
+do { char dstr[30]; \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", dstr); \
+ fprintf (FILE, "\t.float %s\n", dstr); \
+ } while (0)
+
+/* This is how to output an assembler line defining an `int' constant. */
+
+#define ASM_OUTPUT_INT(FILE, VALUE) \
+( fprintf (FILE, "\t.long "), \
+ output_addr_const (FILE, (VALUE)), \
+ fprintf (FILE, "\n"))
+
+/* Likewise for `char' and `short' constants. */
+
+#define ASM_OUTPUT_SHORT(FILE, VALUE) \
+( fprintf (FILE, "\t.hword "), \
+ output_addr_const (FILE, (VALUE)), \
+ fprintf (FILE, "\n"))
+
+#define ASM_OUTPUT_CHAR(FILE, VALUE) \
+( fprintf (FILE, "\t.byte "), \
+ output_addr_const (FILE, (VALUE)), \
+ fprintf (FILE, "\n"))
+
+/* This is how to output an assembler line for a numeric constant byte. */
+#define ASM_OUTPUT_BYTE(FILE, VALUE) \
+ fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
+
+/* Define the parentheses used to group arithmetic operations
+ in assembler code. */
+
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
+
+/* This says how to output the assembler to define a global
+ uninitialized but not common symbol.
+ Try to use asm_output_bss to implement this macro. */
+
+#define ASM_OUTPUT_BSS(FILE, DECL, NAME, SIZE, ROUNDED) \
+ asm_output_bss ((FILE), (DECL), (NAME), (SIZE), (ROUNDED))
+
+/* 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) \
+ do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
+
+/* 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) \
+ do { fputs ("\t.global ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
+
+/* This is how to output a reference to a user-level label named NAME.
+ `assemble_name' uses this. */
+
+#undef ASM_OUTPUT_LABELREF
+#define ASM_OUTPUT_LABELREF(FILE, NAME) \
+ do { \
+ char* real_name; \
+ STRIP_NAME_ENCODING (real_name, (NAME)); \
+ fprintf (FILE, "_%s", real_name); \
+ } 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 we tell the assembler that two symbols have the same value. */
+
+#define ASM_OUTPUT_DEF(FILE,NAME1,NAME2) \
+ do { assemble_name(FILE, NAME1); \
+ fputs(" = ", FILE); \
+ assemble_name(FILE, NAME2); \
+ fputc('\n', FILE); } while (0)
+
+
+/* How to refer to registers in assembler output.
+ This sequence is indexed by compiler's hard-register-number (see above). */
+
+#define REGISTER_NAMES \
+{ "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3"}
+
+/* Print an instruction operand X on file FILE.
+ look in mn10200.c for details */
+
+#define PRINT_OPERAND(FILE, X, CODE) print_operand(FILE,X,CODE)
+
+/* Print a memory operand whose address is X, on file FILE.
+ This uses a function in output-vax.c. */
+
+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
+
+#define ASM_OUTPUT_REG_PUSH(FILE,REGNO)
+#define ASM_OUTPUT_REG_POP(FILE,REGNO)
+
+/* This is how to output an element of a case-vector that is absolute. */
+
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
+ asm_fprintf (FILE, "\t%s .L%d\n", ".long", VALUE)
+
+/* This is how to output an element of a case-vector that is relative. */
+
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
+ fprintf (FILE, "\t%s .L%d-.L%d\n", ".long", VALUE, REL)
+
+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
+ if ((LOG) != 0) \
+ fprintf (FILE, "\t.align %d\n", (LOG))
+
+/* We don't have to worry about dbx compatibility for the mn10200. */
+#define DEFAULT_GDB_EXTENSIONS 1
+
+/* Use stabs debugging info by default. */
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+#define DBX_REGISTER_NUMBER(REGNO) REGNO
+
+/* GDB always assumes the current function's frame begins at the value
+ of the stack pointer upon entry to the current function. Accessing
+ local variables and parameters passed on the stack is done using the
+ base of the frame + an offset provided by GCC.
+
+ For functions which have frame pointers this method works fine;
+ the (frame pointer) == (stack pointer at function entry) and GCC provides
+ an offset relative to the frame pointer.
+
+ This loses for functions without a frame pointer; GCC provides an offset
+ which is relative to the stack pointer after adjusting for the function's
+ frame size. GDB would prefer the offset to be relative to the value of
+ the stack pointer at the function's entry. Yuk! */
+#define DEBUGGER_AUTO_OFFSET(X) \
+ ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) \
+ + (frame_pointer_needed ? 0 : -total_frame_size ()))
+
+#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
+ ((GET_CODE (X) == PLUS ? OFFSET : 0) \
+ + (frame_pointer_needed ? 0 : -total_frame_size ()))
+
+/* Define to use software floating point emulator for REAL_ARITHMETIC and
+ decimal <-> binary conversion. */
+#define REAL_ARITHMETIC
+
+/* Specify the machine mode that this machine uses
+ for the index in the tablejump instruction. */
+#define CASE_VECTOR_MODE Pmode
+
+/* Define this if the case instruction drops through after the table
+ when the index is out of range. Don't define it if the case insn
+ jumps to the default label instead. */
+#define CASE_DROPS_THROUGH
+
+/* Dispatch tables on the mn10200 are extremely expensive in terms of code
+ and readonly data size. So we crank up the case threshold value to
+ encourage a series of if/else comparisons to implement many small switch
+ statements. In theory, this value could be increased much more if we
+ were solely optimizing for space, but we keep it "reasonable" to avoid
+ serious code efficiency lossage. */
+#define CASE_VALUES_THRESHOLD 8
+
+/* Define if operations between registers always perform the operation
+ on the full register even if a narrower mode is specified. */
+#define WORD_REGISTER_OPERATIONS
+
+/* We could define this either way. Using ZERO_EXTEND for QImode makes slightly
+ fast and more compact code. */
+#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
+
+/* Specify the tree operation to be used to convert reals to integers. */
+#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
+
+/* This flag, if defined, says the same insns that convert to a signed fixnum
+ also convert validly to an unsigned one. */
+#define FIXUNS_TRUNC_LIKE_FIX_TRUNC
+
+/* This is the kind of divide that is easiest to do in the general case. */
+#define EASY_DIV_EXPR TRUNC_DIV_EXPR
+
+/* Max number of bytes we can move from memory to memory
+ in one reasonably fast instruction. */
+#define MOVE_MAX 2
+
+/* Define if shifts truncate the shift count
+ which implies one can omit a sign-extension or zero-extension
+ of a shift count. */
+#define SHIFT_COUNT_TRUNCATED 1
+
+/* 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) (OUTPREC != 32)
+
+/* 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 PSImode
+
+/* 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
+
+/* Perform target dependent optabs initialization. */
+#define MODHI3_LIBCALL "__modhi3"
+#define DIVHI3_LIBCALL "__divhi3"
+
+#define INIT_TARGET_OPTABS \
+ do { \
+ sdiv_optab->handlers[(int) HImode].libfunc \
+ = gen_rtx (SYMBOL_REF, Pmode, DIVHI3_LIBCALL); \
+ smod_optab->handlers[(int) HImode].libfunc \
+ = gen_rtx (SYMBOL_REF, Pmode, MODHI3_LIBCALL); \
+ } while (0)
+
+/* The assembler op to get a word. */
+
+#define FILE_ASM_OP "\t.file\n"
+
+extern void asm_file_start ();
+extern void print_operand ();
+extern void print_operand_address ();
+extern void expand_prologue ();
+extern void expand_epilogue ();
+extern void notice_update_cc ();
+extern int call_address_operand ();
+extern enum reg_class secondary_reload_class ();
+extern char *emit_a_shift ();
+extern int current_function_needs_context;
+extern char *output_tst ();
+extern int extendpsi_operand ();
+extern int rtx_equal_function_value_matters;
+extern struct rtx_def *zero_dreg;
+extern struct rtx_def *zero_areg;
diff --git a/gnu/usr.bin/gcc/config/mn10200/mn10200.md b/gnu/usr.bin/gcc/config/mn10200/mn10200.md
new file mode 100644
index 00000000000..9dc753c3023
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10200/mn10200.md
@@ -0,0 +1,1978 @@
+;; GCC machine description for Matsushita MN10200
+;; Copyright (C) 1997 Free Software Foundation, Inc.
+
+;; Contributed by Jeff Law (law@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.
+
+;; 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.
+
+;; Condition code settings.
+;; none - insn does not affect cc
+;; none_0hit - insn does not affect cc but it does modify operand 0
+;; This attribute is used to keep track of when operand 0 changes.
+;; See the description of NOTICE_UPDATE_CC for more info.
+;; set_znv - sets z,n,v to usable values; c is unknown.
+;; set_zn - sets z,n to usable values; v,c is unknown.
+;; compare - compare instruction
+;; clobber - value of cc is unknown
+(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
+ (const_string "clobber"))
+
+;; ----------------------------------------------------------------------
+;; MOVE INSTRUCTIONS
+;; ----------------------------------------------------------------------
+;;
+;; Some general notes on move instructions.
+;;
+;; The hardware can't encode nop moves involving data registers, so
+;; we catch them and emit a nop instead.
+;;
+;; Loads/stores to/from address registers must be 16bit aligned,
+;; thus we avoid them for QImode.
+;;
+;; Stores from address registers always store 24bits, so avoid
+;; stores from address registers in HImode, SImode, and SFmode.
+;;
+;; As a result of the various problems using address registers in
+;; QImode, HImode, SImode, and SFmode, we discourage their use via
+;; '*' in their constraints. They're still allowed, but they're never
+;; the preferred class for for insns with those modes.
+
+;; movqi
+
+(define_expand "movqi"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (match_operand:QI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register */
+ if (!register_operand (operand0, QImode)
+ && !register_operand (operand1, QImode))
+ operands[1] = copy_to_mode_reg (QImode, operand1);
+}")
+
+;; We avoid memory operations involving address registers because we
+;; can't be sure they'll be suitably aligned.
+;;
+;; We also discourage holding QImode values in address registers.
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=d,d,*a,d,d,m,d,*a,*a")
+ (match_operand:QI 1 "general_operand" "0,I,I,di,m,d,*a,d,i*a"))]
+ "register_operand (operands[0], QImode)
+ || register_operand (operands[1], QImode)"
+ "@
+ nop
+ sub %0,%0
+ sub %0,%0
+ mov %S1,%0
+ movbu %1,%0
+ movb %1,%0
+ mov %1,%0
+ mov %1,%0
+ mov %1,%0"
+ [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+
+;; movhi
+
+(define_expand "movhi"
+ [(set (match_operand:HI 0 "general_operand" "")
+ (match_operand:HI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register */
+ if (!register_operand (operand1, HImode)
+ && !register_operand (operand0, HImode))
+ operands[1] = copy_to_mode_reg (HImode, operand1);
+}")
+
+(define_insn ""
+ [(set (match_operand:HI 0 "general_operand" "=d,d,*a,d,d,m,d,*a,*a,*a")
+ (match_operand:HI 1 "general_operand" "0,I,I,di,m,d,*a,d,i*a,m"))]
+ "register_operand (operands[0], HImode)
+ || register_operand (operands[1], HImode)"
+ "@
+ nop
+ sub %0,%0
+ sub %0,%0
+ mov %s1,%0
+ mov %1,%0
+ mov %1,%0
+ mov %1,%0
+ mov %1,%0
+ mov %1,%0
+ mov %A1,%0"
+ [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+
+;; movpsi and helpers
+
+(define_expand "movpsi"
+ [(set (match_operand:PSI 0 "general_operand" "")
+ (match_operand:PSI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register */
+ if (!register_operand (operand1, PSImode)
+ && !register_operand (operand0, PSImode))
+ operands[1] = copy_to_mode_reg (PSImode, operand1);
+}")
+
+
+;; Constant and indexed addresses are not valid addresses for PSImode,
+;; therefore they won't be matched by the general movpsi pattern below.
+;; ??? We had patterns to handle indexed addresses, but they kept making
+;; us run out of regs, so they were eliminated.
+
+(define_insn ""
+ [(set (match_operand:PSI 0 "register_operand" "=a")
+ (match_operand:PSI 1 "constant_memory_operand" ""))]
+ ""
+ "mov %A1,%0"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn ""
+ [(set (match_operand:PSI 0 "constant_memory_operand" "=X")
+ (match_operand:PSI 1 "register_operand" "a"))]
+ ""
+ "mov %1,%A0"
+ [(set_attr "cc" "none_0hit")])
+
+;; We want to prefer address registers here because 24bit moves to/from
+;; memory are shorter and faster when done via address registers.
+(define_insn ""
+ [(set (match_operand:PSI 0 "general_operand" "=d,a?d,?da,a,m,?d,m")
+ (match_operand:PSI 1 "general_operand" "0,I,?dai,m,a,m,?d"))]
+ "register_operand (operands[0], PSImode)
+ || register_operand (operands[1], PSImode)"
+ "@
+ nop
+ sub %0,%0
+ mov %1,%0
+ mov %A1,%0
+ mov %1,%A0
+ movx %A1,%0
+ movx %1,%A0"
+ [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+
+(define_expand "movsi"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (match_operand:SI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register */
+ if (!register_operand (operand1, SImode)
+ && !register_operand (operand0, SImode))
+ operands[1] = copy_to_mode_reg (SImode, operand1);
+}")
+
+(define_insn ""
+ [(set (match_operand:SI 0 "general_operand" "=d,d,*a,dm,d,d,*a,*a,*a")
+ (match_operand:SI 1 "general_operand" "0,I,I,d,dim,*a,d,*a,i"))]
+ "register_operand (operands[0], SImode)
+ || register_operand (operands[1], SImode)"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return \"nop\";
+ case 1:
+ case 2:
+ return \"sub %H0,%H0\;sub %L0,%L0\";
+ case 3:
+ case 5:
+ case 6:
+ case 7:
+ return \"mov %H1,%H0\;mov %L1,%L0\";
+
+ /* The next two cases try to optimize cases where one half
+ of the constant is all zeros, or when the two halves are
+ the same. */
+ case 4:
+ case 8:
+ if (REG_P (operands[0])
+ && GET_CODE (operands[1]) == CONST_INT
+ && (INTVAL (operands[1]) & 0xffff0000) == 0)
+ output_asm_insn (\"sub %H0,%H0\", operands);
+ else
+ output_asm_insn (\"mov %h1,%H0\", operands);
+
+ if (GET_CODE (operands[1]) == CONST_INT
+ && ((INTVAL (operands[1]) & 0xffff)
+ == ((INTVAL (operands[1]) >> 16) & 0xffff)))
+ output_asm_insn (\"mov %H0,%L0\", operands);
+ else if (GET_CODE (operands[1]) == CONST_INT
+ && (INTVAL (operands[1]) & 0xffff) == 0)
+ output_asm_insn (\"sub %L0,%L0\", operands);
+ else
+ output_asm_insn (\"mov %o1,%L0\", operands);
+ return \"\";
+ }
+}"
+ [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+
+(define_expand "movsf"
+ [(set (match_operand:SF 0 "general_operand" "")
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register */
+ if (!register_operand (operand1, SFmode)
+ && !register_operand (operand0, SFmode))
+ operands[1] = copy_to_mode_reg (SFmode, operand1);
+}")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "general_operand" "=d,d,*a,dm,d,d,*a,*a,*a")
+ (match_operand:SF 1 "general_operand" "0,G,G,d,dim,*a,d,*a,i"))]
+ "register_operand (operands[0], SFmode)
+ || register_operand (operands[1], SFmode)"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return \"nop\";
+
+ case 1:
+ case 2:
+ return \"sub %H0,%H0\;sub %L0,%L0\";
+
+ default:
+ {
+ long val;
+ REAL_VALUE_TYPE rv;
+
+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ {
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
+ }
+
+ if (GET_CODE (operands[1]) == CONST_INT)
+ val = INTVAL (operands[1]);
+
+ if ((GET_CODE (operands[1]) == CONST_INT
+ || GET_CODE (operands[1]) == CONST_DOUBLE)
+ && (val & 0xffff0000) == 0)
+ output_asm_insn (\"sub %H0,%H0\", operands);
+ else
+ output_asm_insn (\"mov %h1,%H0\", operands);
+
+ if (GET_CODE (operands[1]) == CONST_INT
+ && ((INTVAL (operands[1]) & 0xffff)
+ == ((INTVAL (operands[1]) >> 16) & 0xffff)))
+ output_asm_insn (\"mov %H0,%L0\", operands);
+ else if ((GET_CODE (operands[1]) == CONST_INT
+ || GET_CODE (operands[1]) == CONST_DOUBLE)
+ && (val & 0x0000ffff) == 0)
+ output_asm_insn (\"sub %L0,%L0\", operands);
+ else
+ output_asm_insn (\"mov %o1,%L0\", operands);
+ return \"\";
+ }
+ }
+}"
+ [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+
+
+;; ----------------------------------------------------------------------
+;; TEST INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+;; Go ahead and define tsthi and tstpsi so we can eliminate redundant tst insns
+;; when we start trying to optimize this port.
+(define_insn "tsthi"
+ [(set (cc0) (match_operand:HI 0 "general_operand" "da"))]
+ ""
+ "* return output_tst (operands[0], insn);"
+ [(set_attr "cc" "set_znv")])
+
+(define_insn "tstpsi"
+ [(set (cc0) (match_operand:PSI 0 "general_operand" "da"))]
+ ""
+ "* return output_tst (operands[0], insn);"
+ [(set_attr "cc" "set_znv")])
+
+(define_insn ""
+ [(set (cc0) (zero_extend:HI (match_operand:QI 0 "memory_operand" "d")))]
+ ""
+ "* return output_tst (operands[0], insn);"
+ [(set_attr "cc" "set_znv")])
+
+(define_insn ""
+ [(set (cc0) (zero_extend:PSI (match_operand:QI 0 "memory_operand" "d")))]
+ ""
+ "* return output_tst (operands[0], insn);"
+ [(set_attr "cc" "set_znv")])
+
+(define_insn "cmphi"
+ [(set (cc0)
+ (compare:HI (match_operand:HI 0 "general_operand" "da")
+ (match_operand:HI 1 "general_operand" "dai")))]
+ ""
+ "cmp %1,%0"
+ [(set_attr "cc" "compare")])
+
+(define_insn "cmppsi"
+ [(set (cc0)
+ (compare:PSI (match_operand:PSI 0 "general_operand" "da")
+ (match_operand:PSI 1 "general_operand" "dai")))]
+ ""
+ "cmp %1,%0"
+ [(set_attr "cc" "compare")])
+
+;; ----------------------------------------------------------------------
+;; ADD INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "addhi3"
+ [(set (match_operand:HI 0 "general_operand" "=d")
+ (plus:HI (match_operand:HI 1 "general_operand" "%0")
+ (match_operand:HI 2 "general_operand" "dai")))]
+ ""
+ "add %2,%0"
+ [(set_attr "cc" "set_zn")])
+
+(define_insn "addpsi3"
+ [(set (match_operand:PSI 0 "general_operand" "=da")
+ (plus:PSI (match_operand:PSI 1 "general_operand" "%0")
+ (match_operand:PSI 2 "general_operand" "dai")))]
+ ""
+ "add %2,%0"
+ [(set_attr "cc" "set_zn")])
+
+;; We want to avoid using explicit registers; reload won't tell us
+;; if it has to spill them and may generate incorrect code in such
+;; cases.
+;;
+;; So we call out to a library routine to perform 32bit add or
+;; subtract operations.
+(define_expand "addsi3"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (plus:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ ""
+ "
+{
+ /* If adding a CONST_INT, we are better off generating code ourselves.
+
+ During RTL generation we call out to library routines.
+
+ After RTL generation we can not call the library routines as
+ they need to push arguments via virtual_outgoing_args_rtx which
+ has already been instantiated. So, after RTL generation we just
+ FAIL and open code the operation. */
+ if (GET_CODE (operands[2]) == CONST_INT)
+ {
+ if (!rtx_equal_p (operands[0], operands[1]))
+ emit_move_insn (operands[0], operands[1]);
+ emit_insn (gen_addsi3_const (operands[0], operands[0], operands[2]));
+ DONE;
+ }
+ else if (rtx_equal_function_value_matters)
+ {
+ rtx ret, insns;
+ extern rtx emit_library_call_value ();
+
+ start_sequence ();
+ ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__addsi3\"),
+ NULL_RTX, 1, SImode, 2, operands[1],
+ SImode, operands[2], SImode);
+ insns = get_insns ();
+ end_sequence ();
+ emit_libcall_block (insns, operands[0], ret,
+ gen_rtx (ASHIFT, SImode, operands[1], operands[2]));
+ DONE;
+ }
+ else
+ FAIL;
+}")
+
+(define_insn "addsi3_const"
+ [(set (match_operand:SI 0 "general_operand" "=d")
+ (plus:SI (match_operand:SI 1 "general_operand" "0")
+ (match_operand:SI 2 "const_int_operand" "i")))
+ (clobber (match_scratch:SI 3 "=&d"))]
+ ""
+ "*
+{
+ unsigned long value = INTVAL (operands[2]);
+
+ /* If only the high bits are set in the constant, then we only
+ need a single add operation. It might be better to catch this
+ at RTL expansion time. */
+ if ((value & 0xffff) == 0)
+ return \"add %h2,%H0\";
+
+ value >>= 16;
+ value &= 0xffff;
+
+ if (value == 0)
+ return \"sub %3,%3\;add %o2,%L0\;addc %3,%H0\";
+ else
+ return \"mov %h2,%3\;add %o2,%L0\;addc %3,%H0\";
+}"
+ [(set_attr "cc" "clobber")])
+
+;; ----------------------------------------------------------------------
+;; SUBTRACT INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "subhi3"
+ [(set (match_operand:HI 0 "general_operand" "=d")
+ (minus:HI (match_operand:HI 1 "general_operand" "0")
+ (match_operand:HI 2 "general_operand" "dai")))]
+ ""
+ "sub %2,%0"
+ [(set_attr "cc" "set_zn")])
+
+(define_insn "subpsi3"
+ [(set (match_operand:PSI 0 "general_operand" "=da")
+ (minus:PSI (match_operand:PSI 1 "general_operand" "0")
+ (match_operand:PSI 2 "general_operand" "dai")))]
+ ""
+ "sub %2,%0"
+ [(set_attr "cc" "set_zn")])
+
+(define_expand "subsi3"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (minus:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ ""
+ "
+{
+ /* During RTL generation we call out to library routines.
+
+ After RTL generation we can not call the library routines as
+ they need to push arguments via virtual_outgoing_args_rtx which
+ has already been instantiated. So, after RTL generation we just
+ FAIL and open code the operation. */
+ if (rtx_equal_function_value_matters)
+ {
+ rtx ret, insns;
+ extern rtx emit_library_call_value ();
+
+ start_sequence ();
+ ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__subsi3\"),
+ NULL_RTX, 1, SImode, 2, operands[1],
+ SImode, operands[2], SImode);
+ insns = get_insns ();
+ end_sequence ();
+ emit_libcall_block (insns, operands[0], ret,
+ gen_rtx (ASHIFT, SImode, operands[1], operands[2]));
+ DONE;
+ }
+ else
+ FAIL;
+}")
+
+;; There isn't a negate instruction, so we fake it.
+;;
+;; We used to expand this into patterns, but a single pattern
+;; actually generates better overall code.
+;;
+;; We could do HImode negations with a "not;add" sequence, but
+;; generally it's generated slightly worse code.
+;;
+;; The second alternative is not strictly necesasry, but helps
+;; when the register allocators start running short of registers.
+(define_insn "neghi2"
+ [(set (match_operand:HI 0 "general_operand" "=&d,d")
+ (neg:HI (match_operand:HI 1 "general_operand" "d,0")))]
+ ""
+ "@
+ sub %0,%0\;sub %1,%0
+ not %0\;add 1,%0"
+ [(set_attr "cc" "set_zn")])
+
+;; The not/and sequence won't work here. It's not clear if we'll
+;; ever need to provide an alternate sequence since this should
+;; be used much less frequently than neghi2.
+(define_insn "negpsi2"
+ [(set (match_operand:PSI 0 "general_operand" "=&d")
+ (neg:PSI (match_operand:PSI 1 "general_operand" "d")))]
+ ""
+ "sub %0,%0\;sub %1,%0"
+ [(set_attr "cc" "set_zn")])
+
+;; Using a magic libcall that accepts its arguments in any
+;; data register pair has proven to be the most efficient
+;; and most compact way to represent negsi2.
+(define_insn "negsi2"
+ [(set (match_operand:SI 0 "general_operand" "=d")
+ (neg:SI (match_operand:SI 1 "general_operand" "0")))]
+ ""
+ "jsr ___negsi2_%0"
+ [(set_attr "cc" "clobber")])
+
+;; ----------------------------------------------------------------------
+;; MULTIPLY INSTRUCTIONS
+;; ----------------------------------------------------------------------
+;;
+;; The mn10200 has HIxHI->SI widening multiply, but we get _severe_
+;; code density regressions if we enable such a pattern.
+
+(define_insn "mulhi3"
+ [(set (match_operand:HI 0 "general_operand" "=d")
+ (mult:HI (match_operand:HI 1 "general_operand" "%0")
+ (match_operand:HI 2 "general_operand" "d")))]
+ ""
+ "mul %2,%0"
+ [(set_attr "cc" "set_zn")])
+
+(define_insn "udivmodhi4"
+ [(set (match_operand:HI 0 "general_operand" "=d")
+ (udiv:HI (match_operand:HI 1 "general_operand" "0")
+ (match_operand:HI 2 "general_operand" "d")))
+ (set (match_operand:HI 3 "general_operand" "=&d")
+ (umod:HI (match_dup 1) (match_dup 2)))]
+ ""
+ "*
+{
+ if (zero_dreg)
+ output_asm_insn (\"mov %0,mdr\", &zero_dreg);
+ else
+ output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
+
+ if (find_reg_note (insn, REG_UNUSED, operands[3]))
+ return \"divu %2,%0\";
+ else
+ return \"divu %2,%0\;mov mdr,%3\";
+}"
+ [(set_attr "cc" "set_zn")])
+
+
+;; ----------------------------------------------------------------------
+;; AND INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "andhi3"
+ [(set (match_operand:HI 0 "general_operand" "=d,d")
+ (and:HI (match_operand:HI 1 "general_operand" "%0,0")
+ (match_operand:HI 2 "general_operand" "M,di")))]
+ ""
+ "*
+{
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
+ return \"extxbu %0\";
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fff)
+ return \"add %0,%0\;lsr %0\";
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffe)
+ return \"lsr %0\;add %0,%0\";
+ return \"and %2,%0\";
+}"
+ [(set_attr "cc" "none_0hit,set_znv")])
+
+;; This expander + pattern exist only to allow trampolines to be aligned
+;; in the stack.
+(define_expand "andpsi3"
+ [(set (match_operand:PSI 0 "general_operand" "")
+ (and:PSI (match_operand:PSI 1 "general_operand" "")
+ (match_operand:PSI 2 "const_int_operand" "")))]
+ ""
+ "
+{
+ if (GET_CODE (operands[2]) != CONST_INT
+ || (INTVAL (operands[2]) & 0xff0000) != 0xff0000)
+ FAIL;
+}")
+
+(define_insn ""
+ [(set (match_operand:PSI 0 "general_operand" "=d")
+ (and:PSI (match_operand:PSI 1 "general_operand" "%0")
+ (match_operand:PSI 2 "const_int_operand" "i")))]
+ "GET_CODE (operands[2]) == CONST_INT
+ && (INTVAL (operands[2]) & 0xff0000) == 0xff0000"
+ "and %2,%0"
+ [(set_attr "cc" "clobber")])
+
+;; ----------------------------------------------------------------------
+;; OR INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "iorhi3"
+ [(set (match_operand:HI 0 "general_operand" "=d")
+ (ior:HI (match_operand:HI 1 "general_operand" "%0")
+ (match_operand:HI 2 "general_operand" "di")))]
+ ""
+ "or %2,%0"
+ [(set_attr "cc" "set_znv")])
+
+;; ----------------------------------------------------------------------
+;; XOR INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "xorhi3"
+ [(set (match_operand:HI 0 "general_operand" "=d")
+ (xor:HI (match_operand:HI 1 "general_operand" "%0")
+ (match_operand:HI 2 "general_operand" "di")))]
+ ""
+ "xor %2,%0"
+ [(set_attr "cc" "set_znv")])
+
+;; ----------------------------------------------------------------------
+;; NOT INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "one_cmplhi2"
+ [(set (match_operand:HI 0 "general_operand" "=d")
+ (not:HI (match_operand:HI 1 "general_operand" "0")))]
+ ""
+ "not %0"
+ [(set_attr "cc" "set_znv")])
+
+
+;; -----------------------------------------------------------------
+;; BIT INSTRUCTIONS
+;; -----------------------------------------------------------------
+
+;; These clears a constant set of bits in memory or in a register.
+;; We must support register destinations to make reload happy.
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "R,d")
+ (subreg:QI
+ (and:HI (subreg:HI (match_dup 0) 0)
+ (match_operand 1 "const_int_operand" "")) 0))
+ (clobber (match_scratch:HI 2 "=&d,X"))]
+ ""
+ "@
+ mov %N1,%2\;bclr %2,%0
+ and %1,%0"
+ [(set_attr "cc" "clobber")])
+
+;; This clears a variable set of bits in memory or in a register.
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "R,d")
+ (subreg:QI
+ (and:HI (subreg:HI (match_dup 0) 0)
+ (not:HI (match_operand:HI 1 "general_operand" "d,d"))) 0))
+ (clobber (match_scratch:HI 2 "=X,&d"))]
+ ""
+ "@
+ bclr %1,%0
+ mov %1,%2\;not %2\;and %2,%0"
+ [(set_attr "cc" "clobber")])
+
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "R,d")
+ (subreg:QI
+ (and:HI (not:HI (match_operand:HI 1 "general_operand" "d,d"))
+ (subreg:HI (match_dup 0) 0)) 0))
+ (clobber (match_scratch:HI 2 "=X,&d"))]
+ ""
+ "@
+ bclr %1,%0
+ mov %1,%2\;not %2\;and %2,%0"
+ [(set_attr "cc" "clobber")])
+
+;; These set bits in memory.
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "R,d")
+ (subreg:QI
+ (ior:HI (subreg:HI (match_dup 0) 0)
+ (match_operand:HI 1 "general_operand" "d,d")) 0))]
+ ""
+ "@
+ bset %1,%0
+ or %1,%0"
+ [(set_attr "cc" "clobber")])
+
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "R,d")
+ (subreg:QI
+ (ior:HI (match_operand:HI 1 "general_operand" "d,d")
+ (subreg:HI (match_dup 0) 0)) 0))]
+ ""
+ "@
+ bset %1,%0
+ or %1,%0"
+ [(set_attr "cc" "clobber")])
+
+;; Not any shorter/faster than using cmp, but it might save a
+;; register if the result of the AND isn't ever used.
+
+(define_insn ""
+ [(set (cc0)
+ (zero_extract:HI (match_operand:HI 0 "general_operand" "d")
+ (match_operand 1 "const_int_operand" "")
+ (match_operand 2 "const_int_operand" "")))]
+ ""
+ "*
+{
+ int len = INTVAL (operands[1]);
+ int bit = INTVAL (operands[2]);
+ int mask = 0;
+ rtx xoperands[2];
+
+ while (len > 0)
+ {
+ mask |= (1 << bit);
+ bit++;
+ len--;
+ }
+
+ xoperands[0] = operands[0];
+ xoperands[1] = GEN_INT (mask);
+ output_asm_insn (\"btst %1,%0\", xoperands);
+ return \"\";
+}"
+ [(set_attr "cc" "set_znv")])
+
+(define_insn ""
+ [(set (cc0) (and:HI (match_operand:HI 0 "general_operand" "d")
+ (match_operand:HI 1 "const_int_operand" "i")))]
+ ""
+ "btst %1,%0"
+ [(set_attr "cc" "set_znv")])
+
+
+;; ----------------------------------------------------------------------
+;; JUMP INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+;; Conditional jump instructions
+
+(define_expand "ble"
+ [(set (pc)
+ (if_then_else (le (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bleu"
+ [(set (pc)
+ (if_then_else (leu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bge"
+ [(set (pc)
+ (if_then_else (ge (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bgeu"
+ [(set (pc)
+ (if_then_else (geu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "blt"
+ [(set (pc)
+ (if_then_else (lt (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bltu"
+ [(set (pc)
+ (if_then_else (ltu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bgt"
+ [(set (pc)
+ (if_then_else (gt (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bgtu"
+ [(set (pc)
+ (if_then_else (gtu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "beq"
+ [(set (pc)
+ (if_then_else (eq (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bne"
+ [(set (pc)
+ (if_then_else (ne (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (match_operator 1 "comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
+ && (GET_CODE (operands[1]) == GT
+ || GET_CODE (operands[1]) == GE
+ || GET_CODE (operands[1]) == LE
+ || GET_CODE (operands[1]) == LT))
+ return 0;
+
+ if (GET_MODE (SET_SRC (PATTERN (PREV_INSN (insn)))) == PSImode)
+ return \"b%b1x %0\";
+ else
+ return \"b%b1 %0\";
+}"
+ [(set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (match_operator 1 "comparison_operator"
+ [(cc0) (const_int 0)])
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
+ && (GET_CODE (operands[1]) == GT
+ || GET_CODE (operands[1]) == GE
+ || GET_CODE (operands[1]) == LE
+ || GET_CODE (operands[1]) == LT))
+ return 0;
+
+ if (GET_MODE (SET_SRC (PATTERN (PREV_INSN (insn)))) == PSImode)
+ return \"b%B1x %0\";
+ else
+ return \"b%B1 %0\";
+}"
+ [(set_attr "cc" "none")])
+
+(define_insn "jump"
+ [(set (pc)
+ (label_ref (match_operand 0 "" "")))]
+ ""
+ "jmp %l0"
+ [(set_attr "cc" "none")])
+
+(define_insn "indirect_jump"
+ [(set (pc) (match_operand:PSI 0 "general_operand" "a"))]
+ ""
+ "jmp (%0)"
+ [(set_attr "cc" "none")])
+
+(define_insn "tablejump"
+ [(set (pc) (match_operand:PSI 0 "general_operand" "a"))
+ (use (label_ref (match_operand 1 "" "")))]
+ ""
+ "jmp (%0)"
+ [(set_attr "cc" "none")])
+
+;; Call subroutine with no return value.
+
+(define_expand "call"
+ [(call (match_operand:QI 0 "general_operand" "")
+ (match_operand:HI 1 "general_operand" ""))]
+ ""
+ "
+{
+ if (! call_address_operand (XEXP (operands[0], 0)))
+ XEXP (operands[0], 0) = force_reg (PSImode, XEXP (operands[0], 0));
+ emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
+ DONE;
+}")
+
+(define_insn "call_internal"
+ [(call (mem:QI (match_operand:PSI 0 "call_address_operand" "aS"))
+ (match_operand:HI 1 "general_operand" "g"))]
+ ""
+ "jsr %C0"
+ [(set_attr "cc" "clobber")])
+
+;; Call subroutine, returning value in operand 0
+;; (which must be a hard register).
+
+(define_expand "call_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "general_operand" "")
+ (match_operand:HI 2 "general_operand" "")))]
+ ""
+ "
+{
+ if (! call_address_operand (XEXP (operands[1], 0)))
+ XEXP (operands[1], 0) = force_reg (PSImode, XEXP (operands[1], 0));
+ emit_call_insn (gen_call_value_internal (operands[0],
+ XEXP (operands[1], 0),
+ operands[2]));
+ DONE;
+}")
+
+(define_insn "call_value_internal"
+ [(set (match_operand 0 "" "=da")
+ (call (mem:QI (match_operand:PSI 1 "call_address_operand" "aS"))
+ (match_operand:HI 2 "general_operand" "g")))]
+ ""
+ "jsr %C1"
+ [(set_attr "cc" "clobber")])
+
+(define_expand "untyped_call"
+ [(parallel [(call (match_operand 0 "" "")
+ (const_int 0))
+ (match_operand 1 "" "")
+ (match_operand 2 "" "")])]
+ ""
+ "
+{
+ int i;
+
+ emit_call_insn (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));
+ }
+ DONE;
+}")
+
+(define_insn "nop"
+ [(const_int 0)]
+ ""
+ "nop"
+ [(set_attr "cc" "none")])
+
+;; ----------------------------------------------------------------------
+;; EXTEND INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "zero_extendqihi2"
+ [(set (match_operand:HI 0 "general_operand" "=d,d,d")
+ (zero_extend:HI
+ (match_operand:QI 1 "general_operand" "0,di,m")))]
+ ""
+ "@
+ extxbu %0
+ mov %1,%0\;extxbu %0
+ movbu %1,%0"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn "zero_extendqipsi2"
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
+ (zero_extend:PSI
+ (match_operand:QI 1 "general_operand" "0,di,m")))]
+ ""
+ "@
+ extxbu %0
+ mov %1,%0\;extxbu %0
+ movbu %1,%0"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn "zero_extendqisi2"
+ [(set (match_operand:SI 0 "general_operand" "=d,d,d")
+ (zero_extend:SI
+ (match_operand:QI 1 "general_operand" "0,di,m")))]
+ ""
+ "@
+ extxbu %L0\;sub %H0,%H0
+ mov %1,%L0\;extxbu %L0\;sub %H0,%H0
+ movbu %1,%L0\;sub %H0,%H0"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn "zero_extendhipsi2"
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
+ (zero_extend:PSI
+ (match_operand:HI 1 "general_operand" "0,di,m")))]
+ ""
+ "@
+ extxu %0
+ mov %1,%0\;extxu %0
+ mov %1,%0\;extxu %0"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn "zero_extendhisi2"
+ [(set (match_operand:SI 0 "general_operand" "=d,d")
+ (zero_extend:SI
+ (match_operand:HI 1 "general_operand" "0,dim")))]
+ ""
+ "@
+ sub %H0,%H0
+ mov %1,%L0\;sub %H0,%H0"
+ [(set_attr "cc" "none_0hit")])
+
+;; The last alternative is necessary because the second operand might
+;; have been the frame pointer. The frame pointer would get replaced
+;; by (plus (stack_pointer) (const_int)).
+;;
+;; Reload would think that it only needed a PSImode register in
+;; push_reload and at the start of allocate_reload_regs. However,
+;; at the end of allocate_reload_reg it would realize that the
+;; reload register must also be valid for SImode, and if it was
+;; not valid reload would abort.
+(define_insn "zero_extendpsisi2"
+ [(set (match_operand:SI 0 "register_operand" "=d,?d,?*d,?*d")
+ (zero_extend:SI (match_operand:PSI 1 "extendpsi_operand"
+ "m,?0,?*dai,Q")))]
+ ""
+ "@
+ mov %L1,%L0\;movbu %H1,%H0
+ jsr ___zero_extendpsisi2_%0
+ mov %1,%L0\;jsr ___zero_extendpsisi2_%0
+ mov a3,%L0\;add %Z1,%L0\;jsr ___zero_extendpsisi2_%0"
+ [(set_attr "cc" "clobber")])
+
+;;- sign extension instructions
+
+(define_insn "extendqihi2"
+ [(set (match_operand:HI 0 "general_operand" "=d,d,d")
+ (sign_extend:HI
+ (match_operand:QI 1 "general_operand" "0,di,m")))]
+ ""
+ "*
+{
+ if (which_alternative == 0)
+ return \"extxb %0\";
+ else if (which_alternative == 1)
+ return \"mov %1,%0\;extxb %0\";
+ else if (GET_CODE (XEXP (operands[1], 0)) == REG)
+ return \"movbu %1,%0\;extxb %0\";
+ else
+ return \"movb %1,%0\";
+}"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn "extendqipsi2"
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
+ (sign_extend:PSI
+ (match_operand:QI 1 "general_operand" "0,di,m")))]
+ ""
+ "*
+{
+ if (which_alternative == 0)
+ return \"extxb %0\";
+ else if (which_alternative == 1)
+ return \"mov %1,%0\;extxb %0\";
+ else if (GET_CODE (XEXP (operands[1], 0)) == REG)
+ return \"movbu %1,%0\;extxb %0\";
+ else
+ return \"movb %1,%0\";
+}"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn "extendqisi2"
+ [(set (match_operand:SI 0 "general_operand" "=d,d,d")
+ (sign_extend:SI
+ (match_operand:QI 1 "general_operand" "0,di,m")))]
+ ""
+ "*
+{
+ if (which_alternative == 0)
+ return \"extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
+ else if (which_alternative == 1)
+ return \"mov %1,%L0\;extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
+ else if (GET_CODE (XEXP (operands[1], 0)) == REG)
+ return \"movbu %1,%L0\;extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
+ else
+ return \"movb %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
+}"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn "extendhipsi2"
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
+ (sign_extend:PSI
+ (match_operand:HI 1 "general_operand" "0,di,m")))]
+ ""
+ "@
+ extx %0
+ mov %1,%0\;extx %0
+ mov %1,%0"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn "extendhisi2"
+ [(set (match_operand:SI 0 "general_operand" "=d,d,d")
+ (sign_extend:SI
+ (match_operand:HI 1 "general_operand" "0,di,m")))]
+ ""
+ "@
+ mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0
+ mov %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0
+ mov %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0"
+ [(set_attr "cc" "none_0hit")])
+
+;; The last alternative is necessary because the second operand might
+;; have been the frame pointer. The frame pointer would get replaced
+;; by (plus (stack_pointer) (const_int)).
+;;
+;; Reload would think that it only needed a PSImode register in
+;; push_reload and at the start of allocate_reload_regs. However,
+;; at the end of allocate_reload_reg it would realize that the
+;; reload register must also be valid for SImode, and if it was
+;; not valid reload would abort.
+(define_insn "extendpsisi2"
+ [(set (match_operand:SI 0 "general_operand" "=d,?d,?*d,?*d")
+ (sign_extend:SI (match_operand:PSI 1 "extendpsi_operand"
+ "m,?0,?*dai,Q")))]
+ ""
+ "@
+ mov %L1,%L0\;movb %H1,%H0
+ jsr ___sign_extendpsisi2_%0
+ mov %1,%L0\;jsr ___sign_extendpsisi2_%0
+ mov a3,%L0\;add %Z1,%L0\;jsr ___sign_extendpsisi2_%0"
+ [(set_attr "cc" "clobber")])
+
+(define_insn "truncsipsi2"
+ [(set (match_operand:PSI 0 "general_operand" "=a,?d,?*d,da")
+ (truncate:PSI (match_operand:SI 1 "general_operand" "m,?m,?*d,i")))]
+ ""
+ "@
+ mov %1,%0
+ movx %A1,%0
+ jsr ___truncsipsi2_%1_%0
+ mov %1,%0"
+ [(set_attr "cc" "clobber")])
+
+
+;; Combine should be simplifying this stuff, but isn't.
+;;
+(define_insn ""
+ [(set (match_operand:SI 0 "general_operand" "=d,d,d")
+ (sign_extend:SI
+ (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m"))))]
+ ""
+ "@
+ extxbu %L0\;sub %H0,%H0
+ mov %1,%L0\;extxbu %L0\;sub %H0,%H0
+ movbu %1,%L0\;sub %H0,%H0"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn ""
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
+ (truncate:PSI
+ (sign_extend:SI (match_operand:QI 1 "general_operand" "0,di,m"))))]
+ ""
+ "*
+{
+ if (which_alternative == 0)
+ return \"extxb %0\";
+ else if (which_alternative == 1)
+ return \"mov %1,%0\;extxb %0\";
+ else if (GET_CODE (XEXP (operands[1], 0)) == REG)
+ return \"movbu %1,%0\;extxb %0\";
+ else
+ return \"movb %1,%0\";
+}"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn ""
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
+ (truncate:PSI
+ (sign_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))))]
+ ""
+ "@
+ extx %0
+ mov %1,%0\;extx %0
+ mov %1,%0"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn ""
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
+ (truncate:PSI
+ (sign_extend:SI
+ (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m")))))]
+ ""
+ "@
+ extxbu %0
+ mov %1,%0\;extxbu %0
+ movbu %1,%0"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn ""
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
+ (truncate:PSI
+ (zero_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))))]
+ ""
+ "@
+ extxu %0
+ mov %1,%0\;extxu %0
+ mov %1,%0\;extxu %0"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn ""
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
+ (truncate:PSI
+ (zero_extend:SI (match_operand:QI 1 "general_operand" "0,di,m"))))]
+ ""
+ "@
+ extxbu %0
+ mov %1,%0\;extxbu %0
+ movbu %1,%0"
+ [(set_attr "cc" "none_0hit")])
+
+;; ----------------------------------------------------------------------
+;; SHIFTS
+;; ----------------------------------------------------------------------
+
+;; If the shift count is small, we expand it into several single bit
+;; shift insns. Otherwise we expand into a generic shift insn which
+;; handles larger shift counts, shift by variable amounts, etc.
+(define_expand "ashlhi3"
+ [(set (match_operand:HI 0 "general_operand" "")
+ (ashift:HI (match_operand:HI 1 "general_operand" "")
+ (match_operand:HI 2 "general_operand" "")))]
+ ""
+ "
+{
+ /* This is an experiment to see if exposing more of the underlying
+ operations results in better code. */
+ if (GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) <= 4)
+ {
+ int count = INTVAL (operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ while (count > 0)
+ {
+ emit_insn (gen_rtx (SET, HImode, operands[0],
+ gen_rtx (ASHIFT, HImode,
+ operands[0], GEN_INT (1))));
+ count--;
+ }
+ DONE;
+ }
+ else
+ {
+ expand_a_shift (HImode, ASHIFT, operands);
+ DONE;
+ }
+}")
+
+;; ASHIFT one bit.
+(define_insn ""
+ [(set (match_operand:HI 0 "general_operand" "=d")
+ (ashift:HI (match_operand:HI 1 "general_operand" "0")
+ (const_int 1)))]
+ ""
+ "add %0,%0"
+ [(set_attr "cc" "set_zn")])
+
+(define_expand "lshrhi3"
+ [(set (match_operand:HI 0 "general_operand" "")
+ (lshiftrt:HI (match_operand:HI 1 "general_operand" "")
+ (match_operand:HI 2 "general_operand" "")))]
+ ""
+ "
+{
+ /* This is an experiment to see if exposing more of the underlying
+ operations results in better code. */
+ if (GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) <= 4)
+ {
+ int count = INTVAL (operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ while (count > 0)
+ {
+ emit_insn (gen_rtx (SET, HImode, operands[0],
+ gen_rtx (LSHIFTRT, HImode,
+ operands[0], GEN_INT (1))));
+ count--;
+ }
+ DONE;
+ }
+ else
+ {
+ expand_a_shift (HImode, LSHIFTRT, operands);
+ DONE;
+ }
+}")
+
+;; LSHIFTRT one bit.
+(define_insn ""
+ [(set (match_operand:HI 0 "general_operand" "=d")
+ (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
+ (const_int 1)))]
+ ""
+ "lsr %0"
+ [(set_attr "cc" "set_znv")])
+
+(define_expand "ashrhi3"
+ [(set (match_operand:HI 0 "general_operand" "")
+ (ashiftrt:HI (match_operand:HI 1 "general_operand" "")
+ (match_operand:HI 2 "general_operand" "")))]
+ ""
+ "
+{
+ /* This is an experiment to see if exposing more of the underlying
+ operations results in better code. */
+ if (GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) <= 4)
+ {
+ int count = INTVAL (operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ while (count > 0)
+ {
+ emit_insn (gen_rtx (SET, HImode, operands[0],
+ gen_rtx (ASHIFTRT, HImode,
+ operands[0], GEN_INT (1))));
+ count--;
+ }
+ DONE;
+ }
+ else
+ {
+ expand_a_shift (HImode, ASHIFTRT, operands);
+ DONE;
+ }
+}")
+
+;; ASHIFTRT one bit.
+(define_insn ""
+ [(set (match_operand:HI 0 "general_operand" "=d")
+ (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
+ (const_int 1)))]
+ ""
+ "asr %0"
+ [(set_attr "cc" "set_znv")])
+
+;; And the general HImode shift pattern. Handles both shift by constants
+;; and shift by variable counts.
+(define_insn ""
+ [(set (match_operand:HI 0 "general_operand" "=d,d")
+ (match_operator:HI 3 "nshift_operator"
+ [ (match_operand:HI 1 "general_operand" "0,0")
+ (match_operand:HI 2 "general_operand" "KL,dan")]))
+ (clobber (match_scratch:HI 4 "=X,&d"))]
+ ""
+ "* return emit_a_shift (insn, operands);"
+ [(set_attr "cc" "clobber")])
+
+;; We expect only ASHIFT with constant shift counts to be common for
+;; PSImode, so we optimize just that case. For all other cases we
+;; extend the value to SImode and perform the shift in SImode.
+(define_expand "ashlpsi3"
+ [(set (match_operand:PSI 0 "general_operand" "")
+ (ashift:PSI (match_operand:PSI 1 "general_operand" "")
+ (match_operand:HI 2 "general_operand" "")))]
+ ""
+ "
+{
+ /* This is an experiment to see if exposing more of the underlying
+ operations results in better code. */
+ if (GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) <= 7)
+ {
+ int count = INTVAL (operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ while (count > 0)
+ {
+ emit_insn (gen_rtx (SET, PSImode, operands[0],
+ gen_rtx (ASHIFT, PSImode,
+ operands[0], GEN_INT (1))));
+ count--;
+ }
+ DONE;
+ }
+ else
+ {
+ expand_a_shift (PSImode, ASHIFT, operands);
+ DONE;
+ }
+}")
+
+;; ASHIFT one bit.
+(define_insn ""
+ [(set (match_operand:PSI 0 "general_operand" "=d")
+ (ashift:PSI (match_operand:PSI 1 "general_operand" "0")
+ (const_int 1)))]
+ ""
+ "add %0,%0"
+ [(set_attr "cc" "set_zn")])
+
+(define_expand "lshrpsi3"
+ [(set (match_operand:PSI 0 "general_operand" "")
+ (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "")
+ (match_operand:HI 2 "general_operand" "")))]
+ ""
+ "
+{
+ rtx reg = gen_reg_rtx (SImode);
+
+ emit_insn (gen_zero_extendpsisi2 (reg, operands[1]));
+ reg = expand_binop (SImode, lshr_optab, reg,
+ operands[2], reg, 1, OPTAB_WIDEN);
+ emit_insn (gen_truncsipsi2 (operands[0], reg));
+ DONE;
+}")
+
+(define_expand "ashrpsi3"
+ [(set (match_operand:PSI 0 "general_operand" "")
+ (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "")
+ (match_operand:HI 2 "general_operand" "")))]
+ ""
+ "
+{
+ rtx reg = gen_reg_rtx (SImode);
+
+ emit_insn (gen_extendpsisi2 (reg, operands[1]));
+ reg = expand_binop (SImode, ashr_optab, reg,
+ operands[2], reg, 0, OPTAB_WIDEN);
+ emit_insn (gen_truncsipsi2 (operands[0], reg));
+ DONE;
+}")
+
+(define_expand "ashlsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (ashift:SI (match_operand:SI 1 "nonmemory_operand" "")
+ (match_operand:HI 2 "general_operand" "")))]
+ ""
+ "
+{
+ /* For small shifts, just emit a series of single bit shifts inline.
+
+ For other constant shift counts smaller than a word or non-constant
+ shift counts we call out to a library call during RTL generation time;
+ after RTL generation time we allow optabs.c to open code the operation.
+ See comments in addsi3/subsi3 expanders.
+
+ Otherwise we allow optabs.c to open code the operation. */
+ if (GET_CODE (operands[2]) == CONST_INT
+ && (INTVAL (operands[2]) <= 3))
+ {
+ int count = INTVAL (operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ while (count > 0)
+ {
+ emit_insn (gen_rtx (SET, SImode, operands[0],
+ gen_rtx (ASHIFT, SImode,
+ operands[0], GEN_INT (1))));
+ count--;
+ }
+ DONE;
+ }
+ else if (rtx_equal_function_value_matters
+ && (GET_CODE (operands[2]) != CONST_INT
+ || INTVAL (operands[2]) <= 15))
+ {
+ rtx ret, insns;
+ extern rtx emit_library_call_value ();
+
+ start_sequence ();
+ ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__ashlsi3\"),
+ NULL_RTX, 1, SImode, 2, operands[1],
+ SImode, operands[2], HImode);
+ insns = get_insns ();
+ end_sequence ();
+ emit_libcall_block (insns, operands[0], ret,
+ gen_rtx (ASHIFT, SImode, operands[1], operands[2]));
+ DONE;
+ }
+ else
+ FAIL;
+}")
+
+;; ASHIFT one bit.
+(define_insn ""
+ [(set (match_operand:SI 0 "general_operand" "=d")
+ (ashift:SI (match_operand:SI 1 "general_operand" "0")
+ (const_int 1)))]
+ ""
+ "add %L0,%L0\;addc %H0,%H0"
+ [(set_attr "cc" "clobber")])
+
+(define_expand "lshrsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (lshiftrt:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:HI 2 "general_operand" "")))]
+ ""
+ "
+{
+ /* For small shifts, just emit a series of single bit shifts inline.
+
+ For other constant shift counts smaller than a word or non-constant
+ shift counts we call out to a library call during RTL generation time;
+ after RTL generation time we allow optabs.c to open code the operation.
+ See comments in addsi3/subsi3 expanders.
+
+ Otherwise we allow optabs.c to open code the operation. */
+ if (GET_CODE (operands[2]) == CONST_INT
+ && (INTVAL (operands[2]) <= 2))
+ {
+ int count = INTVAL (operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ while (count > 0)
+ {
+ emit_insn (gen_rtx (SET, SImode, operands[0],
+ gen_rtx (LSHIFTRT, SImode,
+ operands[0], GEN_INT (1))));
+ count--;
+ }
+ DONE;
+ }
+ else if (rtx_equal_function_value_matters
+ && (GET_CODE (operands[2]) != CONST_INT
+ || INTVAL (operands[2]) <= 15))
+ {
+ rtx ret, insns;
+ extern rtx emit_library_call_value ();
+
+ start_sequence ();
+ ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__lshrsi3\"),
+ NULL_RTX, 1, SImode, 2, operands[1],
+ SImode, operands[2], HImode);
+ insns = get_insns ();
+ end_sequence ();
+ emit_libcall_block (insns, operands[0], ret,
+ gen_rtx (LSHIFTRT, SImode, operands[1], operands[2]));
+ DONE;
+ }
+ else
+ FAIL;
+}")
+
+;; LSHIFTRT one bit.
+(define_insn ""
+ [(set (match_operand:SI 0 "general_operand" "=d")
+ (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
+ (const_int 1)))]
+ ""
+ "lsr %H0\;ror %L0"
+ [(set_attr "cc" "clobber")])
+
+(define_expand "ashrsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:HI 2 "general_operand" "")))]
+ ""
+ "
+{
+ /* For small shifts, just emit a series of single bit shifts inline.
+
+ For other constant shift counts smaller than a word or non-constant
+ shift counts we call out to a library call during RTL generation time;
+ after RTL generation time we allow optabs.c to open code the operation.
+ See comments in addsi3/subsi3 expanders.
+
+ Otherwise we allow optabs.c to open code the operation. */
+ if (GET_CODE (operands[2]) == CONST_INT
+ && (INTVAL (operands[2]) <= 2))
+ {
+ int count = INTVAL (operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ while (count > 0)
+ {
+ emit_insn (gen_rtx (SET, SImode, operands[0],
+ gen_rtx (ASHIFTRT, SImode,
+ operands[0], GEN_INT (1))));
+ count--;
+ }
+ DONE;
+ }
+ else if (rtx_equal_function_value_matters
+ && (GET_CODE (operands[2]) != CONST_INT
+ || INTVAL (operands[2]) <= 15))
+ {
+ rtx ret, insns;
+ extern rtx emit_library_call_value ();
+
+ start_sequence ();
+ ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__ashrsi3\"),
+ NULL_RTX, 1, SImode, 2, operands[1],
+ SImode, operands[2], HImode);
+ insns = get_insns ();
+ end_sequence ();
+ emit_libcall_block (insns, operands[0], ret,
+ gen_rtx (ASHIFTRT, SImode, operands[1], operands[2]));
+ DONE;
+ }
+ else
+ FAIL;
+}")
+
+;; ASHIFTRT one bit.
+(define_insn ""
+ [(set (match_operand:SI 0 "general_operand" "=d")
+ (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
+ (const_int 1)))]
+ ""
+ "asr %H0\;ror %L0"
+ [(set_attr "cc" "clobber")])
+
+;; ----------------------------------------------------------------------
+;; PROLOGUE/EPILOGUE
+;; ----------------------------------------------------------------------
+(define_expand "prologue"
+ [(const_int 0)]
+ ""
+ "expand_prologue (); DONE;")
+
+(define_insn "outline_prologue_call"
+ [(const_int 1)]
+ ""
+ "jsr ___prologue"
+ [(set_attr "cc" "clobber")])
+
+(define_expand "epilogue"
+ [(return)]
+ ""
+ "
+{
+ expand_epilogue ();
+ DONE;
+}")
+
+(define_insn "outline_epilogue_call_a0"
+ [(const_int 2)]
+ ""
+ "jsr ___epilogue_a0"
+ [(set_attr "cc" "clobber")])
+
+(define_insn "outline_epilogue_call_d0"
+ [(const_int 3)]
+ ""
+ "jsr ___epilogue_d0"
+ [(set_attr "cc" "clobber")])
+
+(define_insn "outline_epilogue_jump"
+ [(const_int 4)]
+ ""
+ "jmp ___epilogue_noreturn"
+ [(set_attr "cc" "clobber")])
+
+(define_insn "return"
+ [(return)]
+ "reload_completed && total_frame_size () == 0
+ && !current_function_needs_context"
+ "*
+{
+ rtx next = next_active_insn (insn);
+
+ if (next
+ && GET_CODE (next) == JUMP_INSN
+ && GET_CODE (PATTERN (next)) == RETURN)
+ return \"\";
+ return \"rts\";
+}"
+ [(set_attr "cc" "clobber")])
+
+(define_insn "return_internal"
+ [(const_int 0)
+ (return)]
+ ""
+ "rts"
+ [(set_attr "cc" "clobber")])
+
+;; These are special combiner patterns to improve array/pointer accesses.
+;;
+;; A typical sequence involves extending an integer/char, shifting it left
+;; a few times, then truncating the value to PSImode.
+;;
+;; This first pattern combines the shifting & truncation operations, by
+;; itself it is a win because the shifts end up occurring in PSImode instead
+;; of SImode. However, it has the secondary effect of giving us the
+;; opportunity to match patterns which allow us to remove the initial
+;; extension completely, which is a big win.
+(define_insn ""
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,a")
+ (truncate:PSI
+ (ashift:SI (match_operand:SI 1 "general_operand" "d,m,m")
+ (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
+ ""
+ "*
+{
+ int count = INTVAL (operands[2]);
+ if (which_alternative == 0)
+ output_asm_insn (\"jsr ___truncsipsi2_%1_%0\", operands);
+ else if (which_alternative == 1)
+ output_asm_insn (\"movx %A1,%0\", operands);
+ else
+ output_asm_insn (\" mov %1,%0\", operands);
+
+ while (count)
+ {
+ output_asm_insn (\"add %0,%0\", operands);
+ count--;
+ }
+ return \"\";
+}"
+ [(set_attr "cc" "clobber")])
+
+;; Similarly, except that we also have zero/sign extension of the
+;; original operand. */
+(define_insn ""
+ [(set (match_operand:PSI 0 "general_operand" "=d,d")
+ (truncate:PSI
+ (ashift:SI
+ (zero_extend:SI (match_operand:HI 1 "general_operand" "0,dim"))
+ (match_operand:HI 2 "const_int_operand" "i,i"))))]
+ ""
+ "*
+{
+ int count = INTVAL (operands[2]);
+
+ /* First extend operand 1 to PSImode. */
+ if (which_alternative == 0)
+ output_asm_insn (\"extxu %0\", operands);
+ else
+ output_asm_insn (\"mov %1,%0\;extxu %0\", operands);
+
+ /* Now do the shifting. */
+ while (count)
+ {
+ output_asm_insn (\"add %0,%0\", operands);
+ count--;
+ }
+ return \"\";
+}"
+ [(set_attr "cc" "clobber")])
+
+(define_insn ""
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
+ (truncate:PSI
+ (ashift:SI
+ (sign_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))
+ (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
+ ""
+ "*
+{
+ int count = INTVAL (operands[2]);
+
+ /* First extend operand 1 to PSImode. */
+ if (which_alternative == 0)
+ output_asm_insn (\"extx %0\", operands);
+ else if (which_alternative == 1)
+ output_asm_insn (\"mov %1,%0\;extx %0\", operands);
+ else
+ output_asm_insn (\"mov %1,%0\", operands);
+
+ /* Now do the shifting. */
+ while (count)
+ {
+ output_asm_insn (\"add %0,%0\", operands);
+ count--;
+ }
+ return \"\";
+}"
+ [(set_attr "cc" "clobber")])
+
+(define_insn ""
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
+ (truncate:PSI
+ (ashift:SI
+ (sign_extend:SI
+ (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m")))
+ (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
+ ""
+ "*
+{
+ int count = INTVAL (operands[2]);
+
+ /* First extend operand 1 to PSImode. */
+ if (which_alternative == 0)
+ output_asm_insn (\"extxbu %0\", operands);
+ else if (which_alternative == 1)
+ output_asm_insn (\"mov %1,%0\;extxbu %0\", operands);
+ else
+ output_asm_insn (\"movbu %1,%0\", operands);
+
+ /* Now do the shifting. */
+ while (count)
+ {
+ output_asm_insn (\"add %0,%0\", operands);
+ count--;
+ }
+ return \"\";
+}"
+ [(set_attr "cc" "clobber")])
+
+(define_insn ""
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
+ (truncate:PSI
+ (ashift:SI
+ (sign_extend:SI
+ (match_operand:QI 1 "general_operand" "0,di,m"))
+ (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
+ ""
+ "*
+{
+ int count = INTVAL (operands[2]);
+
+ /* First extend operand 1 to PSImode. */
+ if (which_alternative == 0)
+ output_asm_insn (\"extxb %0\", operands);
+ else if (which_alternative == 1)
+ output_asm_insn (\"mov %1,%0\;extxb %0\", operands);
+ else if (GET_CODE (XEXP (operands[1], 0)) == REG)
+ output_asm_insn (\"movbu %1,%0\;extxb %0\", operands);
+ else
+ output_asm_insn (\"movb %1,%0\", operands);
+
+ /* Now do the shifting. */
+ while (count)
+ {
+ output_asm_insn (\"add %0,%0\", operands);
+ count--;
+ }
+ return \"\";
+}"
+ [(set_attr "cc" "clobber")])
+
+;; Try to combine consecutive updates of the stack pointer (or any
+;; other register for that matter).
+(define_peephole
+ [(set (match_operand:PSI 0 "register_operand" "=da")
+ (plus:PSI (match_dup 0)
+ (match_operand 1 "const_int_operand" "")))
+ (set (match_dup 0)
+ (plus:PSI (match_dup 0)
+ (match_operand 2 "const_int_operand" "")))]
+ ""
+ "*
+{
+ operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
+ return \"add %1,%0\";
+}"
+ [(set_attr "cc" "clobber")])
+
+;;
+;; We had patterns to check eq/ne, but the they don't work because
+;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
+;;
+;; The Z flag and C flag would be set, and we have no way to
+;; check for the Z flag set and C flag clear.
+;;
+;; This will work on the mn10200 because we can check the ZX flag
+;; if the comparison is in HImode.
+(define_peephole
+ [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
+ (set (pc) (if_then_else (ge (cc0) (const_int 0))
+ (match_operand 1 "" "")
+ (pc)))]
+ "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
+ "add %0,%0\;bcc %1"
+ [(set_attr "cc" "clobber")])
+
+(define_peephole
+ [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
+ (set (pc) (if_then_else (lt (cc0) (const_int 0))
+ (match_operand 1 "" "")
+ (pc)))]
+ "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
+ "add %0,%0\;bcs %1"
+ [(set_attr "cc" "clobber")])
+
+(define_peephole
+ [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
+ (set (pc) (if_then_else (ge (cc0) (const_int 0))
+ (pc)
+ (match_operand 1 "" "")))]
+ "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
+ "add %0,%0\;bcs %1"
+ [(set_attr "cc" "clobber")])
+
+(define_peephole
+ [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
+ (set (pc) (if_then_else (lt (cc0) (const_int 0))
+ (pc)
+ (match_operand 1 "" "")))]
+ "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
+ "add %0,%0\;bcc %1"
+ [(set_attr "cc" "clobber")])
+
+(define_peephole
+ [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
+ (set (pc) (if_then_else (ge (cc0) (const_int 0))
+ (match_operand 1 "" "")
+ (pc)))]
+ "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
+ "add %0,%0\;bccx %1"
+ [(set_attr "cc" "clobber")])
+
+(define_peephole
+ [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
+ (set (pc) (if_then_else (lt (cc0) (const_int 0))
+ (match_operand 1 "" "")
+ (pc)))]
+ "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
+ "add %0,%0\;bcsx %1"
+ [(set_attr "cc" "clobber")])
+
+(define_peephole
+ [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
+ (set (pc) (if_then_else (ge (cc0) (const_int 0))
+ (pc)
+ (match_operand 1 "" "")))]
+ "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
+ "add %0,%0\;bcsx %1"
+ [(set_attr "cc" "clobber")])
+
+(define_peephole
+ [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
+ (set (pc) (if_then_else (lt (cc0) (const_int 0))
+ (pc)
+ (match_operand 1 "" "")))]
+ "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
+ "add %0,%0\;bccx %1"
+ [(set_attr "cc" "clobber")])
+
+;; We call out to library routines to perform 32bit addition and subtraction
+;; operations (see addsi3/subsi3 expanders for why). These peepholes catch
+;; the trivial case where the operation could be done with an add;addc or
+;; sub;subc sequence.
+(define_peephole
+ [(set (mem:SI (reg:PSI 7)) (reg:SI 2))
+ (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "")
+ (match_operand:HI 2 "general_operand" "")))]
+ "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
+ && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__addsi3\") == 0"
+ "add d2,d0\;addc d3,d1"
+ [(set_attr "cc" "clobber")])
+
+(define_peephole
+ [(set (mem:SI (reg:PSI 7)) (reg:SI 2))
+ (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "")
+ (match_operand:HI 2 "general_operand" "")))]
+ "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
+ && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__subsi3\") == 0"
+ "sub d2,d0\;subc d3,d1"
+ [(set_attr "cc" "clobber")])
diff --git a/gnu/usr.bin/gcc/config/mn10200/t-mn10200 b/gnu/usr.bin/gcc/config/mn10200/t-mn10200
new file mode 100644
index 00000000000..9486837cd9a
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10200/t-mn10200
@@ -0,0 +1,50 @@
+LIBGCC1=libgcc1.null
+CROSS_LIBGCC1 = libgcc1-asm.a
+LIB1ASMSRC = mn10200/lib1funcs.asm
+LIB1ASMFUNCS = _divhi3 \
+ _modhi3 \
+ _addsi3 \
+ _subsi3 \
+ _mulsi3 \
+ _ashlsi3 \
+ _lshrsi3 \
+ _ashrsi3 \
+ _negsi2_d0 \
+ _negsi2_d2 \
+ _zero_extendpsisi2_d0 \
+ _zero_extendpsisi2_d2 \
+ _sign_extendpsisi2_d0 \
+ _sign_extendpsisi2_d2 \
+ _truncsipsi2_d0_d0 \
+ _truncsipsi2_d0_d1 \
+ _truncsipsi2_d0_d2 \
+ _truncsipsi2_d0_d3 \
+ _truncsipsi2_d2_d0 \
+ _truncsipsi2_d2_d1 \
+ _truncsipsi2_d2_d2 \
+ _truncsipsi2_d2_d3 \
+ _cmpsi2 \
+ _ucmpsi2 \
+ _prologue \
+ _epilogue_a0 \
+ _epilogue_d0 \
+ _epilogue_noreturn
+
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so...
+
+# We do not have DF or DI types, so fake out the libgcc2 compilation.
+TARGET_LIBGCC2_CFLAGS=-DDF=SF -DDI=SI
+LIB2FUNCS_EXTRA = fp-bit.c $(srcdir)/config/mn10200/udivmodsi4.c \
+ $(srcdir)/config/mn10200/divmod.c $(srcdir)/config/mn10200/udivmod.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ echo '#define FLOAT_ONLY' >> fp-bit.c
+ echo '#define SMALL_MACHINE' >> fp-bit.c
+ echo '#define CMPtype HItype' >> fp-bit.c
+ echo '#ifdef __LITTLE_ENDIAN__' >> fp-bit.c
+ echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c
+ echo '#endif' >> fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
diff --git a/gnu/usr.bin/gcc/config/mn10200/udivmod.c b/gnu/usr.bin/gcc/config/mn10200/udivmod.c
new file mode 100644
index 00000000000..1395e9cc940
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10200/udivmod.c
@@ -0,0 +1,14 @@
+long udivmodsi4 ();
+
+long
+__udivsi3 (long a, long b)
+{
+ return udivmodsi4 (a, b, 0);
+}
+
+long
+__umodsi3 (long a, long b)
+{
+ return udivmodsi4 (a, b, 1);
+}
+
diff --git a/gnu/usr.bin/gcc/config/mn10200/udivmodsi4.c b/gnu/usr.bin/gcc/config/mn10200/udivmodsi4.c
new file mode 100644
index 00000000000..83c2340c2f8
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10200/udivmodsi4.c
@@ -0,0 +1,24 @@
+unsigned long
+udivmodsi4(unsigned long num, unsigned long den, int modwanted)
+{
+ unsigned long bit = 1;
+ unsigned long res = 0;
+
+ while (den < num && bit && !(den & (1L<<31)))
+ {
+ den <<=1;
+ bit <<=1;
+ }
+ while (bit)
+ {
+ if (num >= den)
+ {
+ num -= den;
+ res |= bit;
+ }
+ bit >>=1;
+ den >>=1;
+ }
+ if (modwanted) return num;
+ return res;
+}
diff --git a/gnu/usr.bin/gcc/config/mn10200/xm-mn10200.h b/gnu/usr.bin/gcc/config/mn10200/xm-mn10200.h
new file mode 100644
index 00000000000..7ebac70ed3f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10200/xm-mn10200.h
@@ -0,0 +1,47 @@
+/* Configuration for Matsushita MN10200.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+
+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 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 16
+#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"
+
+#ifndef __STDC__
+extern char *malloc (), *realloc (), *calloc ();
+#else
+extern void *malloc (), *realloc (), *calloc ();
+#endif
+extern void free ();
diff --git a/gnu/usr.bin/gcc/config/mn10300/mn10300.c b/gnu/usr.bin/gcc/config/mn10300/mn10300.c
new file mode 100644
index 00000000000..f46e4232083
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10300/mn10300.c
@@ -0,0 +1,1065 @@
+/* Subroutines for insn-output.c for Matsushita MN10300 series
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Jeff Law (law@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 "config.h"
+#include <stdio.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 "flags.h"
+#include "recog.h"
+#include "expr.h"
+#include "tree.h"
+#include "obstack.h"
+
+/* Global registers known to hold the value zero.
+
+ Normally we'd depend on CSE and combine to put zero into a
+ register and re-use it.
+
+ However, on the mn10x00 processors we implicitly use the constant
+ zero in tst instructions, so we might be able to do better by
+ loading the value into a register in the prologue, then re-useing
+ that register throughout the function.
+
+ We could perform similar optimizations for other constants, but with
+ gcse due soon, it doesn't seem worth the effort.
+
+ These variables hold a rtx for a register known to hold the value
+ zero throughout the entire function, or NULL if no register of
+ the appropriate class has such a value throughout the life of the
+ function. */
+rtx zero_dreg;
+rtx zero_areg;
+
+void
+asm_file_start (file)
+ FILE *file;
+{
+ fprintf (file, "#\tGCC For the Matsushita MN10300\n");
+ if (optimize)
+ fprintf (file, "# -O%d\n", optimize);
+ else
+ fprintf (file, "\n\n");
+ output_file_directive (file, main_input_filename);
+}
+
+
+/* Print operand X using operand code CODE to assembly language output file
+ FILE. */
+
+void
+print_operand (file, x, code)
+ FILE *file;
+ rtx x;
+ int code;
+{
+ switch (code)
+ {
+ case 'b':
+ case 'B':
+ /* These are normal and reversed branches. */
+ switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
+ {
+ case NE:
+ fprintf (file, "ne");
+ break;
+ case EQ:
+ fprintf (file, "eq");
+ break;
+ case GE:
+ fprintf (file, "ge");
+ break;
+ case GT:
+ fprintf (file, "gt");
+ break;
+ case LE:
+ fprintf (file, "le");
+ break;
+ case LT:
+ fprintf (file, "lt");
+ break;
+ case GEU:
+ fprintf (file, "cc");
+ break;
+ case GTU:
+ fprintf (file, "hi");
+ break;
+ case LEU:
+ fprintf (file, "ls");
+ break;
+ case LTU:
+ fprintf (file, "cs");
+ break;
+ default:
+ abort ();
+ }
+ break;
+ case 'C':
+ /* This is used for the operand to a call instruction;
+ if it's a REG, enclose it in parens, else output
+ the operand normally. */
+ if (GET_CODE (x) == REG)
+ {
+ fputc ('(', file);
+ print_operand (file, x, 0);
+ fputc (')', file);
+ }
+ else
+ print_operand (file, x, 0);
+ break;
+
+ /* These are the least significant word in a 64bit value. */
+ case 'L':
+ switch (GET_CODE (x))
+ {
+ case MEM:
+ fputc ('(', file);
+ output_address (XEXP (x, 0));
+ fputc (')', file);
+ break;
+
+ case REG:
+ fprintf (file, "%s", reg_names[REGNO (x)]);
+ break;
+
+ case SUBREG:
+ fprintf (file, "%s",
+ reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)]);
+ break;
+
+ case CONST_DOUBLE:
+ {
+ long val[2];
+ REAL_VALUE_TYPE rv;
+
+ switch (GET_MODE (x))
+ {
+ case DFmode:
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+ REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
+ print_operand_address (file, GEN_INT (val[0]));
+ break;;
+ case SFmode:
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+ REAL_VALUE_TO_TARGET_SINGLE (rv, val[0]);
+ print_operand_address (file, GEN_INT (val[0]));
+ break;;
+ case VOIDmode:
+ case DImode:
+ print_operand_address (file,
+ GEN_INT (CONST_DOUBLE_LOW (x)));
+ break;
+ }
+ break;
+ }
+
+ case CONST_INT:
+ print_operand_address (file, x);
+ break;
+
+ default:
+ abort ();
+ }
+ break;
+
+ /* Similarly, but for the most significant word. */
+ case 'H':
+ switch (GET_CODE (x))
+ {
+ case MEM:
+ fputc ('(', file);
+ x = adj_offsettable_operand (x, 4);
+ output_address (XEXP (x, 0));
+ fputc (')', file);
+ break;
+
+ case REG:
+ fprintf (file, "%s", reg_names[REGNO (x) + 1]);
+ break;
+
+ case SUBREG:
+ fprintf (file, "%s",
+ reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)] + 1);
+ break;
+
+ case CONST_DOUBLE:
+ {
+ long val[2];
+ REAL_VALUE_TYPE rv;
+
+ switch (GET_MODE (x))
+ {
+ case DFmode:
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+ REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
+ print_operand_address (file, GEN_INT (val[1]));
+ break;;
+ case SFmode:
+ abort ();
+ case VOIDmode:
+ case DImode:
+ print_operand_address (file,
+ GEN_INT (CONST_DOUBLE_HIGH (x)));
+ break;
+ }
+ break;
+ }
+
+ case CONST_INT:
+ if (INTVAL (x) < 0)
+ print_operand_address (file, GEN_INT (-1));
+ else
+ print_operand_address (file, GEN_INT (0));
+ break;
+ default:
+ abort ();
+ }
+ break;
+
+ case 'A':
+ fputc ('(', file);
+ if (GET_CODE (XEXP (x, 0)) == REG)
+ output_address (gen_rtx (PLUS, SImode, XEXP (x, 0), GEN_INT (0)));
+ else
+ output_address (XEXP (x, 0));
+ fputc (')', file);
+ break;
+
+ case 'N':
+ output_address (GEN_INT ((~INTVAL (x)) & 0xff));
+ break;
+
+ /* For shift counts. The hardware ignores the upper bits of
+ any immediate, but the assembler will flag an out of range
+ shift count as an error. So we mask off the high bits
+ of the immediate here. */
+ case 'S':
+ if (GET_CODE (x) == CONST_INT)
+ {
+ fprintf (file, "%d", INTVAL (x) & 0x1f);
+ break;
+ }
+ /* FALL THROUGH */
+
+ default:
+ switch (GET_CODE (x))
+ {
+ case MEM:
+ fputc ('(', file);
+ output_address (XEXP (x, 0));
+ fputc (')', file);
+ break;
+
+ case PLUS:
+ output_address (x);
+ break;
+
+ case REG:
+ fprintf (file, "%s", reg_names[REGNO (x)]);
+ break;
+
+ case SUBREG:
+ fprintf (file, "%s",
+ reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)]);
+ break;
+
+ /* This will only be single precision.... */
+ case CONST_DOUBLE:
+ {
+ unsigned long val;
+ REAL_VALUE_TYPE rv;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
+ print_operand_address (file, GEN_INT (val));
+ break;
+ }
+
+ case CONST_INT:
+ case SYMBOL_REF:
+ case CONST:
+ case LABEL_REF:
+ case CODE_LABEL:
+ print_operand_address (file, x);
+ break;
+ default:
+ abort ();
+ }
+ break;
+ }
+}
+
+/* Output assembly language output for the address ADDR to FILE. */
+
+void
+print_operand_address (file, addr)
+ FILE *file;
+ rtx addr;
+{
+ switch (GET_CODE (addr))
+ {
+ case REG:
+ if (addr == stack_pointer_rtx)
+ print_operand_address (file, gen_rtx (PLUS, SImode,
+ stack_pointer_rtx,
+ GEN_INT (0)));
+ else
+ print_operand (file, addr, 0);
+ break;
+ case PLUS:
+ {
+ rtx base, index;
+ if (REG_P (XEXP (addr, 0))
+ && REG_OK_FOR_BASE_P (XEXP (addr, 0)))
+ base = XEXP (addr, 0), index = XEXP (addr, 1);
+ else if (REG_P (XEXP (addr, 1))
+ && REG_OK_FOR_BASE_P (XEXP (addr, 1)))
+ base = XEXP (addr, 1), index = XEXP (addr, 0);
+ else
+ abort ();
+ print_operand (file, index, 0);
+ fputc (',', file);
+ print_operand (file, base, 0);;
+ break;
+ }
+ case SYMBOL_REF:
+ output_addr_const (file, addr);
+ break;
+ default:
+ output_addr_const (file, addr);
+ break;
+ }
+}
+
+int
+can_use_return_insn ()
+{
+ /* size includes the fixed stack space needed for function calls. */
+ int size = get_frame_size () + current_function_outgoing_args_size;
+
+ /* And space for the return pointer. */
+ size += current_function_outgoing_args_size ? 4 : 0;
+
+ return (reload_completed
+ && size == 0
+ && !regs_ever_live[2]
+ && !regs_ever_live[3]
+ && !regs_ever_live[6]
+ && !regs_ever_live[7]
+ && !frame_pointer_needed);
+}
+
+/* Count the number of tst insns which compare a data or address
+ register with zero. */
+static void
+count_tst_insns (dreg_countp, areg_countp)
+ int *dreg_countp;
+ int *areg_countp;
+{
+ rtx insn;
+
+ /* Assume no tst insns exist. */
+ *dreg_countp = 0;
+ *areg_countp = 0;
+
+ /* If not optimizing, then quit now. */
+ if (!optimize)
+ return;
+
+ /* Walk through all the insns. */
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ rtx pat;
+
+ /* Ignore anything that is not a normal INSN. */
+ if (GET_CODE (insn) != INSN)
+ continue;
+
+ /* Ignore anything that isn't a SET. */
+ pat = PATTERN (insn);
+ if (GET_CODE (pat) != SET)
+ continue;
+
+ /* Check for a tst insn. */
+ if (SET_DEST (pat) == cc0_rtx
+ && GET_CODE (SET_SRC (pat)) == REG)
+ {
+ if (REGNO_REG_CLASS (REGNO (SET_SRC (pat))) == DATA_REGS)
+ (*dreg_countp)++;
+
+ if (REGNO_REG_CLASS (REGNO (SET_SRC (pat))) == ADDRESS_REGS)
+ (*areg_countp)++;
+ }
+
+ /* Setting an address register to zero can also be optimized,
+ so count it just like a tst insn. */
+ if (GET_CODE (SET_DEST (pat)) == REG
+ && GET_CODE (SET_SRC (pat)) == CONST_INT
+ && INTVAL (SET_SRC (pat)) == 0
+ && REGNO_REG_CLASS (REGNO (SET_DEST (pat))) == ADDRESS_REGS)
+ (*areg_countp)++;
+ }
+}
+
+void
+expand_prologue ()
+{
+ unsigned int size;
+
+ /* We need to end the current sequence so that count_tst_insns can
+ look at all the insns in this function. Normally this would be
+ unsafe, but it's OK in the prologue/epilogue expanders. */
+ end_sequence ();
+
+ /* Determine if it is profitable to put the value zero into a register
+ for the entire function. If so, set ZERO_DREG and ZERO_AREG. */
+ if (regs_ever_live[2] || regs_ever_live[3]
+ || regs_ever_live[6] || regs_ever_live[7]
+ || frame_pointer_needed)
+ {
+ int dreg_count, areg_count;
+
+ /* Get a count of the number of tst insns which use address and
+ data registers. */
+ count_tst_insns (&dreg_count, &areg_count);
+
+ /* If there's more than one tst insn using a data register, then
+ this optimization is a win. */
+ if (dreg_count > 1
+ && (!regs_ever_live[2] || !regs_ever_live[3]))
+ {
+ if (!regs_ever_live[2])
+ {
+ regs_ever_live[2] = 1;
+ zero_dreg = gen_rtx (REG, SImode, 2);
+ }
+ else
+ {
+ regs_ever_live[3] = 1;
+ zero_dreg = gen_rtx (REG, SImode, 3);
+ }
+ }
+ else
+ zero_dreg = NULL_RTX;
+
+ /* If there's more than two tst insns using an address register,
+ then this optimization is a win. */
+ if (areg_count > 2
+ && (!regs_ever_live[6] || !regs_ever_live[7]))
+ {
+ if (!regs_ever_live[6])
+ {
+ regs_ever_live[6] = 1;
+ zero_areg = gen_rtx (REG, SImode, 6);
+ }
+ else
+ {
+ regs_ever_live[7] = 1;
+ zero_areg = gen_rtx (REG, SImode, 7);
+ }
+ }
+ else
+ zero_areg = NULL_RTX;
+ }
+ else
+ {
+ zero_dreg = NULL_RTX;
+ zero_areg = NULL_RTX;
+ }
+
+ /* Start a new sequence. */
+ start_sequence ();
+
+ /* SIZE includes the fixed stack space needed for function calls. */
+ size = get_frame_size () + current_function_outgoing_args_size;
+ size += (current_function_outgoing_args_size ? 4 : 0);
+
+ /* If this is an old-style varargs function, then its arguments
+ need to be flushed back to the stack. */
+ if (current_function_varargs)
+ {
+ emit_move_insn (gen_rtx (MEM, SImode,
+ gen_rtx (PLUS, Pmode, stack_pointer_rtx,
+ GEN_INT (4))),
+ gen_rtx (REG, SImode, 0));
+ emit_move_insn (gen_rtx (MEM, SImode,
+ gen_rtx (PLUS, Pmode, stack_pointer_rtx,
+ GEN_INT (8))),
+ gen_rtx (REG, SImode, 1));
+ }
+
+ /* And now store all the registers onto the stack with a
+ single two byte instruction. */
+ if (regs_ever_live[2] || regs_ever_live[3]
+ || regs_ever_live[6] || regs_ever_live[7]
+ || frame_pointer_needed)
+ emit_insn (gen_store_movm ());
+
+ /* Now put the frame pointer into the frame pointer register. */
+ if (frame_pointer_needed)
+ emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
+
+ /* Allocate stack for this frame. */
+ if (size)
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT (-size)));
+
+ /* Load zeros into registers as needed. */
+ if (zero_dreg)
+ emit_move_insn (zero_dreg, const0_rtx);
+
+ if (zero_areg)
+ emit_move_insn (zero_areg, const0_rtx);
+}
+
+void
+expand_epilogue ()
+{
+ unsigned int size;
+
+ /* SIZE includes the fixed stack space needed for function calls. */
+ size = get_frame_size () + current_function_outgoing_args_size;
+ size += (current_function_outgoing_args_size ? 4 : 0);
+
+ /* Maybe cut back the stack, except for the register save area.
+
+ If the frame pointer exists, then use the frame pointer to
+ cut back the stack.
+
+ If the stack size + register save area is more than 255 bytes,
+ then the stack must be cut back here since the size + register
+ save size is too big for a ret/retf instruction.
+
+ Else leave it alone, it will be cut back as part of the
+ ret/retf instruction, or there wasn't any stack to begin with.
+
+ Under no circumstances should the register save area be
+ deallocated here, that would leave a window where an interrupt
+ could occur and trash the register save area. */
+ if (frame_pointer_needed)
+ {
+ emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+ size = 0;
+ }
+ else if ((regs_ever_live[2] || regs_ever_live[3]
+ || regs_ever_live[6] || regs_ever_live[7])
+ && size + 16 > 255)
+ {
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT (size)));
+ size = 0;
+ }
+
+ /* For simplicity, we just movm all the callee saved registers to
+ the stack with one instruction.
+
+ ?!? Only save registers which are actually used. Reduces
+ stack requirements and is faster. */
+ if (regs_ever_live[2] || regs_ever_live[3]
+ || regs_ever_live[6] || regs_ever_live[7]
+ || frame_pointer_needed)
+ emit_jump_insn (gen_return_internal_regs (GEN_INT (size + 16)));
+ else
+ {
+ if (size)
+ {
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT (size)));
+ emit_jump_insn (gen_return_internal ());
+ }
+ else
+ {
+ emit_jump_insn (gen_return ());
+ }
+ }
+}
+
+/* Update the condition code from the insn. */
+
+void
+notice_update_cc (body, insn)
+ rtx body;
+ rtx insn;
+{
+ switch (get_attr_cc (insn))
+ {
+ case CC_NONE:
+ /* Insn does not affect CC at all. */
+ break;
+
+ case CC_NONE_0HIT:
+ /* Insn does not change CC, but the 0'th operand has been changed. */
+ if (cc_status.value1 != 0
+ && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
+ cc_status.value1 = 0;
+ break;
+
+ case CC_SET_ZN:
+ /* Insn sets the Z,N flags of CC to recog_operand[0].
+ V,C are unusable. */
+ CC_STATUS_INIT;
+ cc_status.flags |= CC_NO_CARRY | CC_OVERFLOW_UNUSABLE;
+ cc_status.value1 = recog_operand[0];
+ break;
+
+ case CC_SET_ZNV:
+ /* Insn sets the Z,N,V flags of CC to recog_operand[0].
+ C is unusable. */
+ CC_STATUS_INIT;
+ cc_status.flags |= CC_NO_CARRY;
+ cc_status.value1 = recog_operand[0];
+ break;
+
+ case CC_COMPARE:
+ /* The insn is a compare instruction. */
+ CC_STATUS_INIT;
+ cc_status.value1 = SET_SRC (body);
+ break;
+
+ case CC_INVERT:
+ /* The insn is a compare instruction. */
+ CC_STATUS_INIT;
+ cc_status.value1 = SET_SRC (body);
+ cc_status.flags |= CC_INVERTED;
+ break;
+
+ case CC_CLOBBER:
+ /* Insn doesn't leave CC in a usable state. */
+ CC_STATUS_INIT;
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+/* Return true if OP is a valid call operand. */
+
+int
+call_address_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
+}
+
+/* What (if any) secondary registers are needed to move IN with mode
+ MODE into a register from in register class CLASS.
+
+ We might be able to simplify this. */
+enum reg_class
+secondary_reload_class (class, mode, in)
+ enum reg_class class;
+ enum machine_mode mode;
+ rtx in;
+{
+ int regno;
+
+ /* Memory loads less than a full word wide can't have an
+ address or stack pointer destination. They must use
+ a data register as an intermediate register. */
+ if (GET_CODE (in) == MEM
+ && (mode == QImode || mode == HImode)
+ && (class == ADDRESS_REGS || class == SP_REGS))
+ return DATA_REGS;
+
+ /* We can't directly load sp + const_int into a data register;
+ we must use an address register as an intermediate. */
+ if (class != SP_REGS
+ && class != ADDRESS_REGS
+ && class != SP_OR_ADDRESS_REGS
+ && (in == stack_pointer_rtx
+ || (GET_CODE (in) == PLUS
+ && (XEXP (in, 0) == stack_pointer_rtx
+ || XEXP (in, 1) == stack_pointer_rtx))))
+ return ADDRESS_REGS;
+
+ if (GET_CODE (in) == PLUS
+ && (XEXP (in, 0) == stack_pointer_rtx
+ || XEXP (in, 1) == stack_pointer_rtx))
+ return DATA_REGS;
+
+
+ /* Otherwise assume no secondary reloads are needed. */
+ return NO_REGS;
+}
+
+int
+initial_offset (from, to)
+ int from, to;
+{
+ /* The difference between the argument pointer and the frame pointer
+ is the size of the callee register save area. */
+ if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
+ {
+ if (regs_ever_live[2] || regs_ever_live[3]
+ || regs_ever_live[6] || regs_ever_live[7]
+ || frame_pointer_needed)
+ return 16;
+ else
+ return 0;
+ }
+
+ /* The difference between the argument pointer and the stack pointer is
+ the sum of the size of this function's frame, the callee register save
+ area, and the fixed stack space needed for function calls (if any). */
+ if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+ {
+ if (regs_ever_live[2] || regs_ever_live[3]
+ || regs_ever_live[6] || regs_ever_live[7]
+ || frame_pointer_needed)
+ return (get_frame_size () + 16
+ + (current_function_outgoing_args_size
+ ? current_function_outgoing_args_size + 4 : 0));
+ else
+ return (get_frame_size ()
+ + (current_function_outgoing_args_size
+ ? current_function_outgoing_args_size + 4 : 0));
+ }
+
+ /* The difference between the frame pointer and stack pointer is the sum
+ of the size of this function's frame and the fixed stack space needed
+ for function calls (if any). */
+ if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+ return (get_frame_size ()
+ + (current_function_outgoing_args_size
+ ? current_function_outgoing_args_size + 4 : 0));
+
+ abort ();
+}
+
+/* Flush the argument registers to the stack for a stdarg function;
+ return the new argument pointer. */
+rtx
+mn10300_builtin_saveregs (arglist)
+ tree arglist;
+{
+ rtx offset;
+ tree fntype = TREE_TYPE (current_function_decl);
+ int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0
+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
+ != void_type_node)))
+ ? UNITS_PER_WORD : 0);
+
+ if (argadj)
+ offset = plus_constant (current_function_arg_offset_rtx, argadj);
+ else
+ offset = current_function_arg_offset_rtx;
+
+ emit_move_insn (gen_rtx (MEM, SImode, current_function_internal_arg_pointer),
+ gen_rtx (REG, SImode, 0));
+ emit_move_insn (gen_rtx (MEM, SImode,
+ plus_constant
+ (current_function_internal_arg_pointer, 4)),
+ gen_rtx (REG, SImode, 1));
+ return copy_to_reg (expand_binop (Pmode, add_optab,
+ current_function_internal_arg_pointer,
+ offset, 0, 0, OPTAB_LIB_WIDEN));
+}
+
+/* Return an RTX to represent where a value with mode MODE will be returned
+ from a function. If the result is 0, the argument is pushed. */
+
+rtx
+function_arg (cum, mode, type, named)
+ CUMULATIVE_ARGS *cum;
+ enum machine_mode mode;
+ tree type;
+ int named;
+{
+ rtx result = 0;
+ int size, align;
+
+ /* We only support using 2 data registers as argument registers. */
+ int nregs = 2;
+
+ /* Figure out the size of the object to be passed. */
+ if (mode == BLKmode)
+ size = int_size_in_bytes (type);
+ else
+ size = GET_MODE_SIZE (mode);
+
+ /* Figure out the alignment of the object to be passed. */
+ align = size;
+
+ cum->nbytes = (cum->nbytes + 3) & ~3;
+
+ /* Don't pass this arg via a register if all the argument registers
+ are used up. */
+ if (cum->nbytes > nregs * UNITS_PER_WORD)
+ return 0;
+
+ /* Don't pass this arg via a register if it would be split between
+ registers and memory. */
+ if (type == NULL_TREE
+ && cum->nbytes + size > nregs * UNITS_PER_WORD)
+ return 0;
+
+ switch (cum->nbytes / UNITS_PER_WORD)
+ {
+ case 0:
+ result = gen_rtx (REG, mode, 0);
+ break;
+ case 1:
+ result = gen_rtx (REG, mode, 1);
+ break;
+ default:
+ result = 0;
+ }
+
+ return result;
+}
+
+/* Return the number of registers to use for an argument passed partially
+ in registers and partially in memory. */
+
+int
+function_arg_partial_nregs (cum, mode, type, named)
+ CUMULATIVE_ARGS *cum;
+ enum machine_mode mode;
+ tree type;
+ int named;
+{
+ int size, align;
+
+ /* We only support using 2 data registers as argument registers. */
+ int nregs = 2;
+
+ /* Figure out the size of the object to be passed. */
+ if (mode == BLKmode)
+ size = int_size_in_bytes (type);
+ else
+ size = GET_MODE_SIZE (mode);
+
+ /* Figure out the alignment of the object to be passed. */
+ align = size;
+
+ cum->nbytes = (cum->nbytes + 3) & ~3;
+
+ /* Don't pass this arg via a register if all the argument registers
+ are used up. */
+ if (cum->nbytes > nregs * UNITS_PER_WORD)
+ return 0;
+
+ if (cum->nbytes + size <= nregs * UNITS_PER_WORD)
+ return 0;
+
+ /* Don't pass this arg via a register if it would be split between
+ registers and memory. */
+ if (type == NULL_TREE
+ && cum->nbytes + size > nregs * UNITS_PER_WORD)
+ return 0;
+
+ return (nregs * UNITS_PER_WORD - cum->nbytes) / UNITS_PER_WORD;
+}
+
+/* Output a tst insn. */
+char *
+output_tst (operand, insn)
+ rtx operand, insn;
+{
+ rtx temp;
+ int past_call = 0;
+
+ /* If we have a data register which is known to be zero throughout
+ the function, then use it instead of doing a search. */
+ if (zero_dreg && REGNO_REG_CLASS (REGNO (operand)) == DATA_REGS)
+ {
+ rtx xoperands[2];
+ xoperands[0] = operand;
+ xoperands[1] = zero_dreg;
+
+ output_asm_insn ("cmp %1,%0", xoperands);
+ return "";
+ }
+
+ /* Similarly for address registers. */
+ if (zero_areg && REGNO_REG_CLASS (REGNO (operand)) == ADDRESS_REGS)
+ {
+ rtx xoperands[2];
+ xoperands[0] = operand;
+ xoperands[1] = zero_areg;
+
+ output_asm_insn ("cmp %1,%0", xoperands);
+ return "";
+ }
+
+ /* We can save a byte if we can find a register which has the value
+ zero in it. */
+ temp = PREV_INSN (insn);
+ while (optimize && temp)
+ {
+ rtx set;
+
+ /* We allow the search to go through call insns. We record
+ the fact that we've past a CALL_INSN and reject matches which
+ use call clobbered registers. */
+ if (GET_CODE (temp) == CODE_LABEL
+ || GET_CODE (temp) == JUMP_INSN
+ || GET_CODE (temp) == BARRIER)
+ break;
+
+ if (GET_CODE (temp) == CALL_INSN)
+ past_call = 1;
+
+ if (GET_CODE (temp) == NOTE)
+ {
+ temp = PREV_INSN (temp);
+ continue;
+ }
+
+ /* It must be an insn, see if it is a simple set. */
+ set = single_set (temp);
+ if (!set)
+ {
+ temp = PREV_INSN (temp);
+ continue;
+ }
+
+ /* Are we setting a data register to zero (this does not win for
+ address registers)?
+
+ If it's a call clobbered register, have we past a call?
+
+ Make sure the register we find isn't the same as ourself;
+ the mn10300 can't encode that. */
+ if (REG_P (SET_DEST (set))
+ && SET_SRC (set) == CONST0_RTX (GET_MODE (SET_DEST (set)))
+ && !reg_set_between_p (SET_DEST (set), temp, insn)
+ && (REGNO_REG_CLASS (REGNO (SET_DEST (set)))
+ == REGNO_REG_CLASS (REGNO (operand)))
+ && REGNO (SET_DEST (set)) != REGNO (operand)
+ && (!past_call
+ || !call_used_regs[REGNO (SET_DEST (set))]))
+ {
+ rtx xoperands[2];
+ xoperands[0] = operand;
+ xoperands[1] = SET_DEST (set);
+
+ output_asm_insn ("cmp %1,%0", xoperands);
+ return "";
+ }
+ temp = PREV_INSN (temp);
+ }
+ return "cmp 0,%0";
+}
+
+int
+impossible_plus_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ extern rtx *reg_equiv_mem;
+ rtx reg1, reg2;
+
+ if (GET_CODE (op) != PLUS)
+ return 0;
+
+ if (XEXP (op, 0) == stack_pointer_rtx
+ || XEXP (op, 1) == stack_pointer_rtx)
+ return 1;
+
+ return 0;
+}
+
+/* Return 1 if X contains a symbolic expression. We know these
+ expressions will have one of a few well defined forms, so
+ we need only check those forms. */
+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;
+ }
+}
+
+/* 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.
+
+ Normally it is always safe for this macro to do nothing. It exists to
+ recognize opportunities to optimize the output.
+
+ But on a few ports with segmented architectures and indexed addressing
+ (mn10300, hppa) it is used to rewrite certain problematical addresses. */
+rtx
+legitimize_address (x, oldx, mode)
+ rtx x;
+ rtx oldx;
+ enum machine_mode mode;
+{
+ /* Uh-oh. We might have an address for x[n-100000]. This needs
+ special handling to avoid creating an indexed memory address
+ with x-100000 as the base. */
+ if (GET_CODE (x) == PLUS
+ && symbolic_operand (XEXP (x, 1), VOIDmode))
+ {
+ /* Ugly. We modify things here so that the address offset specified
+ by the index expression is computed first, then added to x to form
+ the entire address. */
+
+ rtx regx1, regx2, regy1, regy2, y;
+
+ /* Strip off any CONST. */
+ y = XEXP (x, 1);
+ if (GET_CODE (y) == CONST)
+ y = XEXP (y, 0);
+
+ if (GET_CODE (y) == PLUS || GET_CODE (y) == MINUS)
+ {
+ regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0));
+ regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0));
+ regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0));
+ regx1 = force_reg (Pmode,
+ gen_rtx (GET_CODE (y), Pmode, regx1, regy2));
+ return force_reg (Pmode, gen_rtx (PLUS, Pmode, regx1, regy1));
+ }
+ }
+ return x;
+}
diff --git a/gnu/usr.bin/gcc/config/mn10300/mn10300.h b/gnu/usr.bin/gcc/config/mn10300/mn10300.h
new file mode 100644
index 00000000000..9ebcec147c1
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10300/mn10300.h
@@ -0,0 +1,1016 @@
+/* Definitions of target machine for GNU compiler. Matsushita MN10300 series
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Jeff Law (law@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 "svr4.h"
+
+#undef ASM_SPEC
+#undef ASM_FINAL_SPEC
+#undef LIB_SPEC
+#undef ENDFILE_SPEC
+#undef LINK_SPEC
+#undef STARTFILE_SPEC
+
+/* Names to predefine in the preprocessor for this target machine. */
+
+#define CPP_PREDEFINES "-D__mn10300__ -D__MN10300__"
+
+/* Run-time compilation parameters selecting different hardware subsets. */
+
+extern int target_flags;
+
+/* Global registers known to hold the value zero. */
+extern struct rtx_def *zero_dreg;
+extern struct rtx_def *zero_areg;
+
+/* Macros used in the machine description to test the flags. */
+
+/* Macro to define tables used to set the flags.
+ This is a list in braces of pairs in braces,
+ each pair being { "NAME", VALUE }
+ where VALUE is the bits to set or minus the bits to clear.
+ An empty string NAME is used to identify the default VALUE. */
+
+/* Generate code to work around mul/mulq bugs on the mn10300. */
+#define TARGET_MULT_BUG (target_flags & 0x1)
+#define TARGET_SWITCHES \
+ {{ "mult-bug", 0x1}, \
+ { "no-mult-bug", -0x1}, \
+ { "", TARGET_DEFAULT}}
+
+#ifndef TARGET_DEFAULT
+#define TARGET_DEFAULT 0x1
+#endif
+
+/* Print subsidiary information on the compiler version in use. */
+
+#define TARGET_VERSION fprintf (stderr, " (MN10300)");
+
+
+/* Target machine storage layout */
+
+/* Define this if most significant bit is lowest numbered
+ in instructions that operate on numbered bit-fields.
+ This is not true on the Matsushita MN1003. */
+#define BITS_BIG_ENDIAN 0
+
+/* Define this if most significant byte of a word is the lowest numbered. */
+/* This is not true on the Matsushita MN10300. */
+#define BYTES_BIG_ENDIAN 0
+
+/* Define this if most significant word of a multiword number is lowest
+ numbered.
+ This is not true on the Matsushita MN10300. */
+#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 68000, 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
+
+/* The stack goes in 32 bit lumps. */
+#define STACK_BOUNDARY 32
+
+/* Allocation boundary (in *bits*) for the code of a function.
+ 8 is the minimum boundary; it's unclear if bigger alignments
+ would improve performance. */
+#define FUNCTION_BOUNDARY 8
+
+/* No data type wants to be aligned rounder than this. */
+#define BIGGEST_ALIGNMENT 32
+
+/* Alignment of field after `int : 0' in a structure. */
+#define EMPTY_FIELD_BOUNDARY 32
+
+/* Define this if move instructions will actually fail to work
+ when given unaligned data. */
+#define STRICT_ALIGNMENT 1
+
+/* Define this as 1 if `char' should by default be signed; else as 0. */
+#define DEFAULT_SIGNED_CHAR 0
+
+/* 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
+
+/* Standard register usage. */
+
+/* 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. */
+
+#define FIRST_PSEUDO_REGISTER 10
+
+/* 1 for registers that have pervasive standard uses
+ and are not available for the register allocator. */
+
+#define FIXED_REGISTERS \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 1, 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 \
+ { 1, 1, 0, 0, 1, 1, 0, 0, 1, 1}
+
+#define REG_ALLOC_ORDER \
+ { 0, 1, 4, 5, 2, 3, 6, 7, 8, 9}
+
+/* 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. */
+
+#define HARD_REGNO_NREGS(REGNO, MODE) \
+ ((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. */
+
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+ (REGNO_REG_CLASS (REGNO) == DATA_REGS \
+ ? ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) <= 4 \
+ : ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) == 4)
+
+/* 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 || GET_MODE_SIZE (MODE1) <= 4 && GET_MODE_SIZE (MODE2) <= 4)
+
+/* 4 data, and effectively 3 address registers is small as far as I'm
+ concerned. */
+#define SMALL_REGISTER_CLASSES 1
+
+/* 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. */
+
+enum reg_class {
+ NO_REGS, DATA_REGS, ADDRESS_REGS, SP_REGS, DATA_OR_ADDRESS_REGS, SP_OR_ADDRESS_REGS, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
+};
+
+#define N_REG_CLASSES (int) LIM_REG_CLASSES
+
+/* Give names of register classes as strings for dump file. */
+
+#define REG_CLASS_NAMES \
+{ "NO_REGS", "DATA_REGS", "ADDRESS_REGS", \
+ "SP_REGS", "DATA_OR_ADDRESS_REGS", "SP_OR_ADDRESS_REGS", \
+ "GENERAL_REGS", "ALL_REGS", "LIM_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, /* No regs */ \
+ 0x00f, /* DATA_REGS */ \
+ 0x1f0, /* ADDRESS_REGS */ \
+ 0x200, /* SP_REGS */ \
+ 0x1ff, /* DATA_OR_ADDRESS_REGS */\
+ 0x1f0, /* SP_OR_ADDRESS_REGS */\
+ 0x1ff, /* GENERAL_REGS */ \
+ 0x3ff, /* ALL_REGS */ \
+}
+
+/* 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) \
+ ((REGNO) < 4 ? DATA_REGS : \
+ (REGNO) < 9 ? ADDRESS_REGS : \
+ (REGNO) == 9 ? SP_REGS: 0)
+
+/* The class value for index registers, and the one for base regs. */
+
+#define INDEX_REG_CLASS DATA_REGS
+#define BASE_REG_CLASS SP_OR_ADDRESS_REGS
+
+/* Get reg_class from a letter such as appears in the machine description. */
+
+#define REG_CLASS_FROM_LETTER(C) \
+ ((C) == 'd' ? DATA_REGS : \
+ (C) == 'a' ? ADDRESS_REGS : \
+ (C) == 'x' ? SP_REGS : NO_REGS)
+
+/* 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_BASE_P(regno) \
+ (((regno) > 3 && regno < FIRST_PSEUDO_REGISTER) \
+ || (reg_renumber[regno] > 3 && reg_renumber[regno] < FIRST_PSEUDO_REGISTER))
+
+#define REGNO_OK_FOR_INDEX_P(regno) \
+ (((regno) >= 0 && regno < 4) \
+ || (reg_renumber[regno] >= 0 && reg_renumber[regno] < 4))
+
+
+/* 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. */
+
+#define PREFERRED_RELOAD_CLASS(X,CLASS) \
+ (X == stack_pointer_rtx && CLASS != SP_REGS ? ADDRESS_REGS : CLASS)
+
+#define PREFERRED_OUTPUT_RELOAD_CLASS(X,CLASS) \
+ (X == stack_pointer_rtx && CLASS != SP_REGS ? ADDRESS_REGS : CLASS)
+
+#define LIMIT_RELOAD_CLASS(MODE, CLASS) \
+ ((MODE == QImode || MODE == HImode) ? DATA_REGS : CLASS)
+
+#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
+ secondary_reload_class(CLASS,MODE,IN)
+
+/* Return the maximum number of consecutive registers
+ needed to represent mode MODE in a register of class CLASS. */
+
+#define CLASS_MAX_NREGS(CLASS, MODE) \
+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* The letters I, J, K, L, M, N, O, P 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. */
+
+#define INT_8_BITS(VALUE) ((unsigned) (VALUE) + 0x80 < 0x100)
+#define INT_16_BITS(VALUE) ((unsigned) (VALUE) + 0x8000 < 0x10000)
+
+#define CONST_OK_FOR_I(VALUE) ((VALUE) == 0)
+#define CONST_OK_FOR_J(VALUE) ((VALUE) == 1)
+#define CONST_OK_FOR_K(VALUE) ((VALUE) == 2)
+#define CONST_OK_FOR_L(VALUE) ((VALUE) == 4)
+#define CONST_OK_FOR_M(VALUE) ((VALUE) == 3)
+#define CONST_OK_FOR_N(VALUE) ((VALUE) == 255 || (VALUE) == 65535)
+
+#define CONST_OK_FOR_LETTER_P(VALUE, C) \
+ ((C) == 'I' ? CONST_OK_FOR_I (VALUE) : \
+ (C) == 'J' ? CONST_OK_FOR_J (VALUE) : \
+ (C) == 'K' ? CONST_OK_FOR_K (VALUE) : \
+ (C) == 'L' ? CONST_OK_FOR_L (VALUE) : \
+ (C) == 'M' ? CONST_OK_FOR_M (VALUE) : \
+ (C) == 'N' ? CONST_OK_FOR_N (VALUE) : 0)
+
+
+/* Similar, but for floating constants, and defining letters G and H.
+ Here VALUE is the CONST_DOUBLE rtx itself.
+
+ `G' is a floating-point zero. */
+
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
+ ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
+ && (VALUE) == CONST0_RTX (GET_MODE (VALUE))) : 0)
+
+
+/* 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
+
+/* Offset of first parameter from the argument pointer register value. */
+/* Is equal to the size of the saved fp + pc, even if an fp isn't
+ saved since the value is used before we know. */
+
+#define FIRST_PARM_OFFSET(FNDECL) 4
+
+/* Specify the registers used for certain standard purposes.
+ The values of these macros are register numbers. */
+
+/* Register to use for pushing function arguments. */
+#define STACK_POINTER_REGNUM 9
+
+/* Base register for access to local variables of the function. */
+#define FRAME_POINTER_REGNUM 7
+
+/* Base register for access to arguments of the function. This
+ is a fake register and will be eliminated into either the frame
+ pointer or stack pointer. */
+#define ARG_POINTER_REGNUM 8
+
+/* Register in which static-chain is passed to a function. */
+#define STATIC_CHAIN_REGNUM 5
+
+#define ELIMINABLE_REGS \
+{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+ { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
+
+#define CAN_ELIMINATE(FROM, TO) 1
+
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ OFFSET = initial_offset (FROM, TO)
+
+/* We can debug without frame pointers on the mn10300, so eliminate
+ them whenever possible. */
+#define FRAME_POINTER_REQUIRED 0
+#define CAN_DEBUG_WITHOUT_FP
+
+/* A guess for the MN10300. */
+#define PROMOTE_PROTOTYPES 1
+
+/* Value is the number of bytes of arguments automatically
+ popped when returning from a subroutine call.
+ FUNDECL is the declaration node of the function (as a tree),
+ FUNTYPE is the data type of the function (as a tree),
+ or for a library call it is an identifier node for the subroutine name.
+ SIZE is the number of bytes of arguments passed on the stack. */
+
+#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
+
+/* We use d0/d1 for passing parameters, so allocate 8 bytes of space
+ for a register flushback area. */
+#define REG_PARM_STACK_SPACE(DECL) 8
+#define OUTGOING_REG_PARM_STACK_SPACE
+#define ACCUMULATE_OUTGOING_ARGS
+
+/* So we can allocate space for return pointers once for the function
+ instead of around every call. */
+#define STACK_POINTER_OFFSET 4
+
+/* 1 if N is a possible register number for function argument passing.
+ On the MN10300, no registers are used in this way. */
+
+#define FUNCTION_ARG_REGNO_P(N) ((N) <= 1)
+
+
+/* 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.
+
+ On the MN10300, this is a single integer, which is a number of bytes
+ of arguments scanned so far. */
+
+#define CUMULATIVE_ARGS struct cum_arg
+struct cum_arg {int nbytes; };
+
+/* 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.
+
+ On the MN10300, the offset starts at 0. */
+
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
+ ((CUM).nbytes = 0)
+
+/* 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) \
+ ((CUM).nbytes += ((MODE) != BLKmode \
+ ? (GET_MODE_SIZE (MODE) + 3) & ~3 \
+ : (int_size_in_bytes (TYPE) + 3) & ~3))
+
+/* 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). */
+
+/* On the MN10300 all args are pushed. */
+
+extern struct rtx_def *function_arg ();
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
+ function_arg (&CUM, MODE, TYPE, NAMED)
+
+#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
+ function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
+
+
+#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
+ ((TYPE) && int_size_in_bytes (TYPE) > 8)
+
+#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
+ ((TYPE) && int_size_in_bytes (TYPE) > 8)
+
+/* 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), POINTER_TYPE_P (VALTYPE) ? 4 : 0)
+
+/* 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, 0)
+
+/* 1 if N is a possible register number for a function value. */
+
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0 || (N) == 4)
+
+/* Return values > 8 bytes in length in memory. */
+#define DEFAULT_PCC_STRUCT_RETURN 0
+#define RETURN_IN_MEMORY(TYPE) \
+ (int_size_in_bytes (TYPE) > 8 || TYPE_MODE (TYPE) == BLKmode)
+
+/* Register in which address to store a structure value
+ is passed to a function. On the MN10300 it's passed as
+ the first parameter. */
+
+#define STRUCT_VALUE 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. */
+
+#define EXIT_IGNORE_STACK 1
+
+/* Output assembler code to FILE to increment profiler label # LABELNO
+ for profiling a function entry. */
+
+#define FUNCTION_PROFILER(FILE, LABELNO) ;
+
+#define TRAMPOLINE_TEMPLATE(FILE) \
+ do { \
+ fprintf (FILE, "\tadd -4,sp\n"); \
+ fprintf (FILE, "\t.long 0x0004fffa\n"); \
+ fprintf (FILE, "\tmov (0,sp),a0\n"); \
+ fprintf (FILE, "\tadd 4,sp\n"); \
+ fprintf (FILE, "\tmov (13,a0),a1\n"); \
+ fprintf (FILE, "\tmov (17,a0),a0\n"); \
+ fprintf (FILE, "\tjmp (a0)\n"); \
+ fprintf (FILE, "\t.long 0\n"); \
+ fprintf (FILE, "\t.long 0\n"); \
+ } while (0)
+
+/* Length in units of the trampoline for entering a nested function. */
+
+#define TRAMPOLINE_SIZE 0x1b
+
+#define TRAMPOLINE_ALIGNMENT 32
+
+/* 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), 0x14)), \
+ (CXT)); \
+ emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 0x18)), \
+ (FNADDR)); \
+}
+/* A C expression whose value is RTL representing the value of the return
+ address for the frame COUNT steps up from the current frame.
+
+ On the mn10300, the return address is not at a constant location
+ due to the frame layout. Luckily, it is at a constant offset from
+ the argument pointer, so we define RETURN_ADDR_RTX to return a
+ MEM using arg_pointer_rtx. Reload will replace arg_pointer_rtx
+ with a reference to the stack/frame pointer + an appropriate offset. */
+
+#define RETURN_ADDR_RTX(COUNT, FRAME) \
+ ((COUNT == 0) \
+ ? gen_rtx (MEM, Pmode, arg_pointer_rtx) \
+ : (rtx) 0)
+
+/* Emit code for a call to builtin_saveregs. We must emit USE insns which
+ reference the 2 integer arg registers.
+ Ordinarily they are not call used registers, but they are for
+ _builtin_saveregs, so we must make this explicit. */
+
+extern struct rtx_def *mn10300_builtin_saveregs ();
+#define EXPAND_BUILTIN_SAVEREGS(ARGLIST) mn10300_builtin_saveregs (ARGLIST)
+
+/* Addressing modes, and classification of registers for them. */
+
+
+/* 1 if X is an rtx for a constant that is a valid address. */
+
+#define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)
+
+/* Extra constraints. */
+
+#define OK_FOR_R(OP) \
+ (GET_CODE (OP) == MEM \
+ && GET_MODE (OP) == QImode \
+ && (CONSTANT_ADDRESS_P (XEXP (OP, 0)) \
+ || (GET_CODE (XEXP (OP, 0)) == REG \
+ && REG_OK_FOR_BASE_P (XEXP (OP, 0)) \
+ && XEXP (OP, 0) != stack_pointer_rtx) \
+ || (GET_CODE (XEXP (OP, 0)) == PLUS \
+ && GET_CODE (XEXP (XEXP (OP, 0), 0)) == REG \
+ && REG_OK_FOR_BASE_P (XEXP (XEXP (OP, 0), 0)) \
+ && XEXP (XEXP (OP, 0), 0) != stack_pointer_rtx \
+ && GET_CODE (XEXP (XEXP (OP, 0), 1)) == CONST_INT \
+ && INT_8_BITS (INTVAL (XEXP (XEXP (OP, 0), 1))))))
+
+#define EXTRA_CONSTRAINT(OP, C) \
+ ((C) == 'R' ? OK_FOR_R (OP) : (C) == 'S' ? GET_CODE (OP) == SYMBOL_REF : 0)
+
+/* Maximum number of registers that can appear in a valid memory address. */
+
+#define MAX_REGS_PER_ADDRESS 2
+
+/* 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. */
+
+#ifndef REG_OK_STRICT
+/* Nonzero if X is a hard reg that can be used as an index
+ or if it is a pseudo reg. */
+#define REG_OK_FOR_INDEX_P(X) \
+ ((REGNO (X) >= 0 && REGNO(X) <= 3) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
+/* Nonzero if X is a hard reg that can be used as a base reg
+ or if it is a pseudo reg. */
+#define REG_OK_FOR_BASE_P(X) \
+ ((REGNO (X) >= 4 && REGNO(X) <= 9) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
+#else
+/* Nonzero if X is a hard reg that can be used as an index. */
+#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+/* Nonzero if X is a hard reg that can be used as a base reg. */
+#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (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 actually
+ machine-independent.
+
+ On the mn10300, the value in the address register must be
+ in the same memory space/segment as the effective address.
+
+ This is problematical for reload since it does not understand
+ that base+index != index+base in a memory reference.
+
+ Note it is still possible to use reg+reg addressing modes,
+ it's just much more difficult. For a discussion of a possible
+ workaround and solution, see the comments in pa.c before the
+ function record_unscaled_index_insn_codes. */
+
+/* Accept either REG or SUBREG where a register is valid. */
+
+#define RTX_OK_FOR_BASE_P(X) \
+ ((REG_P (X) && REG_OK_FOR_BASE_P (X)) \
+ || (GET_CODE (X) == SUBREG && REG_P (SUBREG_REG (X)) \
+ && REG_OK_FOR_BASE_P (SUBREG_REG (X))))
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+{ \
+ if (CONSTANT_ADDRESS_P (X)) \
+ goto ADDR; \
+ if (RTX_OK_FOR_BASE_P (X)) \
+ goto ADDR; \
+ if (GET_CODE (X) == PLUS) \
+ { \
+ rtx base = 0, index = 0; \
+ if (REG_P (XEXP (X, 0)) \
+ && REG_OK_FOR_BASE_P (XEXP (X, 0))) \
+ base = XEXP (X, 0), index = XEXP (X, 1); \
+ if (REG_P (XEXP (X, 1)) \
+ && REG_OK_FOR_BASE_P (XEXP (X, 1))) \
+ base = XEXP (X, 1), index = XEXP (X, 0); \
+ if (base != 0 && index != 0) \
+ { \
+ if (GET_CODE (index) == CONST_INT) \
+ goto ADDR; \
+ } \
+ } \
+}
+
+
+/* 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. */
+
+extern struct rtx_def *legitimize_address ();
+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
+{ rtx orig_x = (X); \
+ (X) = legitimize_address (X, OLDX, MODE); \
+ if ((X) != orig_x && memory_address_p (MODE, X)) \
+ goto WIN; }
+
+/* Go to LABEL if ADDR (a legitimate address expression)
+ has an effect that depends on the machine mode it is used for. */
+
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) {}
+
+/* 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
+
+
+/* Tell final.c how to eliminate redundant test instructions. */
+
+/* Here we define machine-dependent flags and fields in cc_status
+ (see `conditions.h'). No extra ones are needed for the vax. */
+
+/* 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 CC_OVERFLOW_UNUSABLE 0x200
+#define CC_NO_CARRY CC_NO_OVERFLOW
+#define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc(EXP, INSN)
+
+/* 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: \
+ /* Zeros are extremely cheap. */ \
+ if (INTVAL (RTX) == 0 && OUTER_CODE == SET) \
+ return 0; \
+ /* If it fits in 8 bits, then it's still relatively cheap. */ \
+ if (INT_8_BITS (INTVAL (RTX))) \
+ return 1; \
+ /* This is the "base" cost, includes constants where either the \
+ upper or lower 16bits are all zeros. */ \
+ if (INT_16_BITS (INTVAL (RTX)) \
+ || (INTVAL (RTX) & 0xffff) == 0 \
+ || (INTVAL (RTX) & 0xffff0000) == 0) \
+ return 2; \
+ return 4; \
+ /* These are more costly than a CONST_INT, but we can relax them, \
+ so they're less costly than a CONST_DOUBLE. */ \
+ case CONST: \
+ case LABEL_REF: \
+ case SYMBOL_REF: \
+ return 6; \
+ /* We don't optimize CONST_DOUBLEs well nor do we relax them well, \
+ so their cost is very high. */ \
+ case CONST_DOUBLE: \
+ return 8;
+
+
+#define REGISTER_MOVE_COST(CLASS1, CLASS2) (CLASS1 != CLASS2 ? 4 : 2)
+
+/* A crude cut at RTX_COSTS for the MN10300. */
+
+/* Provide the costs of a rtl expression. This is in the body of a
+ switch on CODE. */
+#define RTX_COSTS(RTX,CODE,OUTER_CODE) \
+ case MOD: \
+ case DIV: \
+ return 8; \
+ case MULT: \
+ return 8;
+
+/* Nonzero if access to memory by bytes or half words is no faster
+ than accessing full words. */
+#define SLOW_BYTE_ACCESS 1
+
+/* Dispatch tables on the mn10300 are extremely expensive in terms of code
+ and readonly data size. So we crank up the case threshold value to
+ encourage a series of if/else comparisons to implement many small switch
+ statements. In theory, this value could be increased much more if we
+ were solely optimizing for space, but we keep it "reasonable" to avoid
+ serious code efficiency lossage. */
+#define CASE_VALUES_THRESHOLD 6
+
+#define NO_FUNCTION_CSE
+
+/* According expr.c, a value of around 6 should minimize code size, and
+ for the MN10300 series, that's our primary concern. */
+#define MOVE_RATIO 6
+
+#define TEXT_SECTION_ASM_OP "\t.section .text"
+#define DATA_SECTION_ASM_OP "\t.section .data"
+#define BSS_SECTION_ASM_OP "\t.section .bss"
+
+/* Output at beginning/end of assembler file. */
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) asm_file_start(FILE)
+
+#define ASM_COMMENT_START "#"
+
+/* 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"
+
+/* This is how to output an assembler line defining a `double' constant.
+ It is .dfloat or .gfloat, depending. */
+
+#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
+do { char dstr[30]; \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", dstr); \
+ fprintf (FILE, "\t.double %s\n", dstr); \
+ } while (0)
+
+
+/* This is how to output an assembler line defining a `float' constant. */
+#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
+do { char dstr[30]; \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", dstr); \
+ fprintf (FILE, "\t.float %s\n", dstr); \
+ } while (0)
+
+/* This is how to output an assembler line defining an `int' constant. */
+
+#define ASM_OUTPUT_INT(FILE, VALUE) \
+( fprintf (FILE, "\t.long "), \
+ output_addr_const (FILE, (VALUE)), \
+ fprintf (FILE, "\n"))
+
+/* Likewise for `char' and `short' constants. */
+
+#define ASM_OUTPUT_SHORT(FILE, VALUE) \
+( fprintf (FILE, "\t.hword "), \
+ output_addr_const (FILE, (VALUE)), \
+ fprintf (FILE, "\n"))
+
+#define ASM_OUTPUT_CHAR(FILE, VALUE) \
+( fprintf (FILE, "\t.byte "), \
+ output_addr_const (FILE, (VALUE)), \
+ fprintf (FILE, "\n"))
+
+/* This is how to output an assembler line for a numeric constant byte. */
+#define ASM_OUTPUT_BYTE(FILE, VALUE) \
+ fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
+
+/* Define the parentheses used to group arithmetic operations
+ in assembler code. */
+
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
+
+/* This says how to output the assembler to define a global
+ uninitialized but not common symbol.
+ Try to use asm_output_bss to implement this macro. */
+
+#define ASM_OUTPUT_BSS(FILE, DECL, NAME, SIZE, ROUNDED) \
+ asm_output_bss ((FILE), (DECL), (NAME), (SIZE), (ROUNDED))
+
+/* 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) \
+ do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
+
+/* 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) \
+ do { fputs ("\t.global ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
+
+/* This is how to output a reference to a user-level label named NAME.
+ `assemble_name' uses this. */
+
+#undef ASM_OUTPUT_LABELREF
+#define ASM_OUTPUT_LABELREF(FILE, NAME) \
+ do { \
+ char* real_name; \
+ STRIP_NAME_ENCODING (real_name, (NAME)); \
+ fprintf (FILE, "_%s", real_name); \
+ } 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 we tell the assembler that two symbols have the same value. */
+
+#define ASM_OUTPUT_DEF(FILE,NAME1,NAME2) \
+ do { assemble_name(FILE, NAME1); \
+ fputs(" = ", FILE); \
+ assemble_name(FILE, NAME2); \
+ fputc('\n', FILE); } while (0)
+
+
+/* How to refer to registers in assembler output.
+ This sequence is indexed by compiler's hard-register-number (see above). */
+
+#define REGISTER_NAMES \
+{ "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp" }
+
+/* Print an instruction operand X on file FILE.
+ look in mn10300.c for details */
+
+#define PRINT_OPERAND(FILE, X, CODE) print_operand(FILE,X,CODE)
+
+/* Print a memory operand whose address is X, on file FILE.
+ This uses a function in output-vax.c. */
+
+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
+
+#define ASM_OUTPUT_REG_PUSH(FILE,REGNO)
+#define ASM_OUTPUT_REG_POP(FILE,REGNO)
+
+/* This is how to output an element of a case-vector that is absolute. */
+
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
+ asm_fprintf (FILE, "\t%s .L%d\n", ".long", VALUE)
+
+/* This is how to output an element of a case-vector that is relative. */
+
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
+ fprintf (FILE, "\t%s .L%d-.L%d\n", ".long", VALUE, REL)
+
+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
+ if ((LOG) != 0) \
+ fprintf (FILE, "\t.align %d\n", (LOG))
+
+/* We don't have to worry about dbx compatibility for the mn10300. */
+#define DEFAULT_GDB_EXTENSIONS 1
+
+/* Use stabs debugging info by default. */
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+#define DBX_REGISTER_NUMBER(REGNO) REGNO
+
+/* Define to use software floating point emulator for REAL_ARITHMETIC and
+ decimal <-> binary conversion. */
+#define REAL_ARITHMETIC
+
+/* Specify the machine mode that this machine uses
+ for the index in the tablejump instruction. */
+#define CASE_VECTOR_MODE Pmode
+
+/* Define this if the case instruction drops through after the table
+ when the index is out of range. Don't define it if the case insn
+ jumps to the default label instead. */
+#define CASE_DROPS_THROUGH
+
+/* Define if operations between registers always perform the operation
+ on the full register even if a narrower mode is specified. */
+#define WORD_REGISTER_OPERATIONS
+
+#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
+
+/* Specify the tree operation to be used to convert reals to integers. */
+#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
+
+/* This flag, if defined, says the same insns that convert to a signed fixnum
+ also convert validly to an unsigned one. */
+#define FIXUNS_TRUNC_LIKE_FIX_TRUNC
+
+/* This is the kind of divide that is easiest to do in the general case. */
+#define EASY_DIV_EXPR TRUNC_DIV_EXPR
+
+/* Max number of bytes we can move from memory to memory
+ in one reasonably fast instruction. */
+#define MOVE_MAX 4
+
+/* Define if shifts truncate the shift count
+ which implies one can omit a sign-extension or zero-extension
+ of a shift count. */
+#define SHIFT_COUNT_TRUNCATED 1
+
+/* 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
+
+/* 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
+
+/* The assembler op to get a word. */
+
+#define FILE_ASM_OP "\t.file\n"
+
+extern void asm_file_start ();
+extern int const_costs ();
+extern void print_operand ();
+extern void print_operand_address ();
+extern void expand_prologue ();
+extern void expand_epilogue ();
+extern void notice_update_cc ();
+extern int call_address_operand ();
+extern int impossible_plus_operand ();
+extern enum reg_class secondary_reload_class ();
+extern int initial_offset ();
+extern char *output_tst ();
+int symbolic_operand ();
diff --git a/gnu/usr.bin/gcc/config/mn10300/mn10300.md b/gnu/usr.bin/gcc/config/mn10300/mn10300.md
new file mode 100644
index 00000000000..2ff8a8162ea
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10300/mn10300.md
@@ -0,0 +1,1415 @@
+;; GCC machine description for Matsushita MN10300
+;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+
+;; Contributed by Jeff Law (law@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.
+
+;; 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.
+
+;; Condition code settings.
+;; none - insn does not affect cc
+;; none_0hit - insn does not affect cc but it does modify operand 0
+;; This attribute is used to keep track of when operand 0 changes.
+;; See the description of NOTICE_UPDATE_CC for more info.
+;; set_znv - insn sets z,n,v to usable values; c is unusable.
+;; set_zn - insn sets z,n to usable values; v,c are unusable.
+;; compare - compare instruction
+;; invert -- like compare, but flags are inverted.
+;; clobber - value of cc is unknown
+(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber,invert"
+ (const_string "clobber"))
+
+;; ----------------------------------------------------------------------
+;; MOVE INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+;; movqi
+
+(define_expand "movqi"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (match_operand:QI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register */
+ if (!register_operand (operand0, QImode)
+ && !register_operand (operand1, QImode))
+ operands[1] = copy_to_mode_reg (QImode, operand1);
+}")
+
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=d,*a,d,*a,d,*a,d,*a,d,m")
+ (match_operand:QI 1 "general_operand" "0,0,I,I,a,d,di,ia,m,d"))]
+ "register_operand (operands[0], QImode)
+ || register_operand (operands[1], QImode)"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ case 1:
+ return \"nop\";
+ case 2:
+ return \"clr %0\";
+ case 3:
+ if (zero_areg)
+ {
+ rtx xoperands[2];
+
+ xoperands[0] = operands[0];
+ xoperands[1] = zero_areg;
+ if (rtx_equal_p (xoperands[0], xoperands[1]))
+ output_asm_insn (\"sub %1,%0\", xoperands);
+ else
+ output_asm_insn (\"mov %1,%0\", xoperands);
+ return \"\";
+ }
+
+ /* FALLTHROUGH */
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ return \"mov %1,%0\";
+ case 8:
+ case 9:
+ return \"movbu %1,%0\";
+ }
+}"
+ [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+
+;; movhi
+
+(define_expand "movhi"
+ [(set (match_operand:HI 0 "general_operand" "")
+ (match_operand:HI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register */
+ if (!register_operand (operand1, HImode)
+ && !register_operand (operand0, HImode))
+ operands[1] = copy_to_mode_reg (HImode, operand1);
+}")
+
+(define_insn ""
+ [(set (match_operand:HI 0 "general_operand" "=d,*a,d,*a,d,*a,d,*a,d,m")
+ (match_operand:HI 1 "general_operand" "0,0,I,I,a,d,di,ia,m,d"))]
+ "register_operand (operands[0], HImode)
+ || register_operand (operands[1], HImode)"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ case 1:
+ return \"nop\";
+ case 2:
+ return \"clr %0\";
+ case 3:
+ if (zero_areg)
+ {
+ rtx xoperands[2];
+
+ xoperands[0] = operands[0];
+ xoperands[1] = zero_areg;
+ if (rtx_equal_p (xoperands[0], xoperands[1]))
+ output_asm_insn (\"sub %1,%0\", xoperands);
+ else
+ output_asm_insn (\"mov %1,%0\", xoperands);
+ return \"\";
+ }
+
+ /* FALLTHROUGH */
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ return \"mov %1,%0\";
+ case 8:
+ case 9:
+ return \"movhu %1,%0\";
+ }
+}"
+ [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+
+;; movsi and helpers
+
+;; We use this to handle addition of two values when one operand is the
+;; stack pointer and the other is a memory reference of some kind. Reload
+;; does not handle them correctly without this expander.
+(define_expand "reload_insi"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (match_operand:SI 1 "impossible_plus_operand" ""))
+ (clobber (match_operand:SI 2 "register_operand" "=&r"))]
+ ""
+ "
+{
+ if (XEXP (operands[1], 0) == stack_pointer_rtx)
+ {
+ emit_move_insn (operands[0], XEXP (operands[1], 0));
+ if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
+ && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
+ > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
+ emit_move_insn (operands[2],
+ gen_rtx (ZERO_EXTEND, GET_MODE (XEXP (operands[1], 1)),
+ SUBREG_REG (XEXP (operands[1], 1))));
+ else
+ emit_move_insn (operands[2], XEXP (operands[1], 1));
+ }
+ else
+ {
+ emit_move_insn (operands[0], XEXP (operands[1], 1));
+ if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
+ && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
+ > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
+ emit_move_insn (operands[2],
+ gen_rtx (ZERO_EXTEND, GET_MODE (XEXP (operands[1], 0)),
+ SUBREG_REG (XEXP (operands[1], 0))));
+ else
+ emit_move_insn (operands[2], XEXP (operands[1], 0));
+ }
+ emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
+ DONE;
+}")
+
+(define_expand "movsi"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (match_operand:SI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register */
+ if (!register_operand (operand1, SImode)
+ && !register_operand (operand0, SImode))
+ operands[1] = copy_to_mode_reg (SImode, operand1);
+}")
+
+(define_insn ""
+ [(set (match_operand:SI 0 "general_operand"
+ "=d,a,d,a,dm,dm,am,am,d,d,a,a,aR,x")
+ (match_operand:SI 1 "general_operand"
+ "0,0,I,I,d,a,d,a,dim,aim,dim,aim,x,aR"))]
+ "register_operand (operands[0], SImode)
+ || register_operand (operands[1], SImode)"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ case 1:
+ return \"nop\";
+ case 2:
+ return \"clr %0\";
+ case 3:
+ if (zero_areg)
+ {
+ rtx xoperands[2];
+
+ xoperands[0] = operands[0];
+ xoperands[1] = zero_areg;
+ if (rtx_equal_p (xoperands[0], xoperands[1]))
+ output_asm_insn (\"sub %1,%0\", xoperands);
+ else
+ output_asm_insn (\"mov %1,%0\", xoperands);
+ return \"\";
+ }
+
+ /* FALLTHROUGH */
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ return \"mov %1,%0\";
+ }
+}"
+ [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+
+(define_expand "movsf"
+ [(set (match_operand:SF 0 "general_operand" "")
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register */
+ if (!register_operand (operand1, SFmode)
+ && !register_operand (operand0, SFmode))
+ operands[1] = copy_to_mode_reg (SFmode, operand1);
+}")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "general_operand" "=d,a,d,a,dam,da")
+ (match_operand:SF 1 "general_operand" "0,0,G,G,da,daim"))]
+ "register_operand (operands[0], SFmode)
+ || register_operand (operands[1], SFmode)"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ case 1:
+ return \"nop\";
+ case 2:
+ return \"clr %0\";
+ case 3:
+ if (zero_areg)
+ {
+ rtx xoperands[2];
+
+ xoperands[0] = operands[0];
+ xoperands[1] = zero_areg;
+ if (rtx_equal_p (xoperands[0], xoperands[1]))
+ output_asm_insn (\"sub %1,%0\", xoperands);
+ else
+ output_asm_insn (\"mov %1,%0\", xoperands);
+ return \"\";
+ }
+
+ /* FALLTHROUGH */
+ case 4:
+ case 5:
+ return \"mov %1,%0\";
+ }
+}"
+ [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")])
+
+(define_expand "movdi"
+ [(set (match_operand:DI 0 "general_operand" "")
+ (match_operand:DI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register */
+ if (!register_operand (operand1, DImode)
+ && !register_operand (operand0, DImode))
+ operands[1] = copy_to_mode_reg (DImode, operand1);
+}")
+
+(define_insn ""
+ [(set (match_operand:DI 0 "general_operand"
+ "=d,a,d,a,dm,dm,am,am,d,d,a,a")
+ (match_operand:DI 1 "general_operand"
+ "0,0,I,I,d,a,d,a,dim,aim,dim,aim"))]
+ "register_operand (operands[0], DImode)
+ || register_operand (operands[1], DImode)"
+ "*
+{
+ long val[2];
+ REAL_VALUE_TYPE rv;
+
+ switch (which_alternative)
+ {
+ case 0:
+ case 1:
+ return \"nop\";
+
+ case 2:
+ return \"clr %L0\;clr %H0\";
+
+ case 3:
+ {
+ rtx xoperands[2];
+
+ xoperands[0] = operands[0];
+ xoperands[1] = zero_areg ? zero_areg : operands[1];
+ if (rtx_equal_p (xoperands[0], xoperands[1]))
+ output_asm_insn (\"sub %L1,%L0\;mov %L0,%H0\", xoperands);
+ else
+ output_asm_insn (\"mov %1,%L0\;mov %L0,%H0\", xoperands);
+ return \"\";
+ }
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ if (GET_CODE (operands[1]) == CONST_INT)
+ {
+ val[0] = INTVAL (operands[1]);
+ val[1] = val[0] < 0 ? -1 : 0;
+ }
+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ {
+ if (GET_MODE (operands[1]) == DFmode)
+ {
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+ REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
+ }
+ else if (GET_MODE (operands[1]) == VOIDmode
+ || GET_MODE (operands[1]) == DImode)
+ {
+ val[0] = CONST_DOUBLE_LOW (operands[1]);
+ val[1] = CONST_DOUBLE_HIGH (operands[1]);
+ }
+ }
+
+ if (GET_CODE (operands[1]) == MEM
+ && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
+ {
+ rtx temp = operands[0];
+
+ while (GET_CODE (temp) == SUBREG)
+ temp = SUBREG_REG (temp);
+
+ if (GET_CODE (temp) != REG)
+ abort ();
+
+ if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
+ XEXP (operands[1], 0)))
+ return \"mov %H1,%H0\;mov %L1,%L0\";
+ else
+ return \"mov %L1,%L0\;mov %H1,%H0\";
+
+ }
+ else if (GET_CODE (operands[1]) == MEM
+ && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
+ && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
+ {
+ rtx xoperands[2];
+
+ xoperands[0] = operands[0];
+ xoperands[1] = XEXP (operands[1], 0);
+
+ output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
+ xoperands);
+ return \"\";
+ }
+ else
+ {
+ if ((GET_CODE (operands[1]) == CONST_INT
+ || GET_CODE (operands[1]) == CONST_DOUBLE)
+ && val[0] == 0)
+ {
+ if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
+ output_asm_insn (\"clr %L0\", operands);
+ else if (zero_areg)
+ {
+ rtx xoperands[2];
+
+ xoperands[0] = operands[0];
+ xoperands[1] = zero_areg;
+ if (rtx_equal_p (xoperands[0], xoperands[1]))
+ output_asm_insn (\"sub %L0,%L0\", xoperands);
+ else
+ output_asm_insn (\"mov %1,%L0\", xoperands);
+ }
+ else
+ output_asm_insn (\"mov %L1,%L0\", operands);
+ }
+ else
+ output_asm_insn (\"mov %L1,%L0\", operands);
+
+ if ((GET_CODE (operands[1]) == CONST_INT
+ || GET_CODE (operands[1]) == CONST_DOUBLE)
+ && val[1] == 0)
+ {
+ if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
+ output_asm_insn (\"clr %H0\", operands);
+ else if (zero_areg)
+ {
+ rtx xoperands[2];
+
+ xoperands[0] = operands[0];
+ xoperands[1] = zero_areg;
+ if (rtx_equal_p (xoperands[0], xoperands[1]))
+ output_asm_insn (\"sub %H0,%H0\", xoperands);
+ else
+ output_asm_insn (\"mov %1,%H0\", xoperands);
+ }
+ else
+ output_asm_insn (\"mov %H1,%H0\", operands);
+ }
+ else if ((GET_CODE (operands[1]) == CONST_INT
+ || GET_CODE (operands[1]) == CONST_DOUBLE)
+ && val[0] == val[1])
+ output_asm_insn (\"mov %L0,%H0\", operands);
+ else
+ output_asm_insn (\"mov %H1,%H0\", operands);
+ return \"\";
+ }
+ }
+}"
+ [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+
+(define_expand "movdf"
+ [(set (match_operand:DF 0 "general_operand" "")
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register */
+ if (!register_operand (operand1, DFmode)
+ && !register_operand (operand0, DFmode))
+ operands[1] = copy_to_mode_reg (DFmode, operand1);
+}")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "general_operand"
+ "=d,a,d,a,dm,dm,am,am,d,d,a,a")
+ (match_operand:DF 1 "general_operand"
+ "0,0,G,G,d,a,d,a,dim,aim,dim,aim"))]
+ "register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode)"
+ "*
+{
+ long val[2];
+ REAL_VALUE_TYPE rv;
+
+ switch (which_alternative)
+ {
+ case 0:
+ case 1:
+ return \"nop\";
+
+ case 2:
+ return \"clr %L0\;clr %H0\";
+
+ case 3:
+ {
+ rtx xoperands[2];
+
+ xoperands[0] = operands[0];
+ xoperands[1] = zero_areg ? zero_areg : operands[1];
+ if (rtx_equal_p (xoperands[0], xoperands[1]))
+ output_asm_insn (\"sub %L1,%L0\;mov %L0,%H0\", xoperands);
+ else
+ output_asm_insn (\"mov %1,%L0\;mov %L0,%H0\", xoperands);
+ return \"\";
+ }
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ if (GET_CODE (operands[1]) == CONST_INT)
+ {
+ val[0] = INTVAL (operands[1]);
+ val[1] = val[0] < 0 ? -1 : 0;
+ }
+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ {
+ if (GET_MODE (operands[1]) == DFmode)
+ {
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+ REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
+ }
+ else if (GET_MODE (operands[1]) == VOIDmode
+ || GET_MODE (operands[1]) == DImode)
+ {
+ val[0] = CONST_DOUBLE_LOW (operands[1]);
+ val[1] = CONST_DOUBLE_HIGH (operands[1]);
+ }
+ }
+
+ if (GET_CODE (operands[1]) == MEM
+ && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
+ {
+ rtx temp = operands[0];
+
+ while (GET_CODE (temp) == SUBREG)
+ temp = SUBREG_REG (temp);
+
+ if (GET_CODE (temp) != REG)
+ abort ();
+
+ if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
+ XEXP (operands[1], 0)))
+ return \"mov %H1,%H0\;mov %L1,%L0\";
+ else
+ return \"mov %L1,%L0\;mov %H1,%H0\";
+
+ }
+ else if (GET_CODE (operands[1]) == MEM
+ && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
+ && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
+ {
+ rtx xoperands[2];
+
+ xoperands[0] = operands[0];
+ xoperands[1] = XEXP (operands[1], 0);
+
+ output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
+ xoperands);
+ return \"\";
+ }
+ else
+ {
+ if ((GET_CODE (operands[1]) == CONST_INT
+ || GET_CODE (operands[1]) == CONST_DOUBLE)
+ && val[0] == 0)
+ {
+ if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
+ output_asm_insn (\"clr %L0\", operands);
+ else if (zero_areg)
+ {
+ rtx xoperands[2];
+
+ xoperands[0] = operands[0];
+ xoperands[1] = zero_areg;
+ if (rtx_equal_p (xoperands[0], xoperands[1]))
+ output_asm_insn (\"sub %L0,%L0\", xoperands);
+ else
+ output_asm_insn (\"mov %1,%L0\", xoperands);
+ }
+ else
+ output_asm_insn (\"mov %L1,%L0\", operands);
+ }
+ else
+ output_asm_insn (\"mov %L1,%L0\", operands);
+
+ if ((GET_CODE (operands[1]) == CONST_INT
+ || GET_CODE (operands[1]) == CONST_DOUBLE)
+ && val[1] == 0)
+ {
+ if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
+ output_asm_insn (\"clr %H0\", operands);
+ else if (zero_areg)
+ {
+ rtx xoperands[2];
+
+ xoperands[0] = operands[0];
+ xoperands[1] = zero_areg;
+ if (rtx_equal_p (xoperands[0], xoperands[1]))
+ output_asm_insn (\"sub %H0,%H0\", xoperands);
+ else
+ output_asm_insn (\"mov %1,%H0\", xoperands);
+ }
+ else
+ output_asm_insn (\"mov %H1,%H0\", operands);
+ }
+ else if ((GET_CODE (operands[1]) == CONST_INT
+ || GET_CODE (operands[1]) == CONST_DOUBLE)
+ && val[0] == val[1])
+ output_asm_insn (\"mov %L0,%H0\", operands);
+ else
+ output_asm_insn (\"mov %H1,%H0\", operands);
+ return \"\";
+ }
+ }
+}"
+ [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+
+
+
+;; ----------------------------------------------------------------------
+;; TEST INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+;; Go ahead and define tstsi so we can eliminate redundant tst insns
+;; when we start trying to optimize this port.
+(define_insn "tstsi"
+ [(set (cc0) (match_operand:SI 0 "register_operand" "da"))]
+ ""
+ "* return output_tst (operands[0], insn);"
+ [(set_attr "cc" "set_znv")])
+
+(define_insn ""
+ [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "d")))]
+ ""
+ "* return output_tst (operands[0], insn);"
+ [(set_attr "cc" "set_znv")])
+
+(define_insn ""
+ [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "d")))]
+ ""
+ "* return output_tst (operands[0], insn);"
+ [(set_attr "cc" "set_znv")])
+
+
+(define_insn "cmpsi"
+ [(set (cc0)
+ (compare (match_operand:SI 0 "register_operand" "!*d*a,da")
+ (match_operand:SI 1 "nonmemory_operand" "!*0,dai")))]
+ ""
+ "@
+ add 0,%0
+ cmp %1,%0"
+ [(set_attr "cc" "invert,compare")])
+
+;; ----------------------------------------------------------------------
+;; ADD INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_expand "addsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))]
+ ""
+ "
+{
+ /* We can't add a variable amount directly to the stack pointer;
+ so do so via a temporary register. */
+ if (operands[0] == stack_pointer_rtx
+ && GET_CODE (operands[1]) != CONST_INT
+ && GET_CODE (operands[2]) != CONST_INT)
+ {
+ rtx temp = gen_reg_rtx (SImode);
+ emit_move_insn (temp, gen_rtx (PLUS, SImode, operands[1], operands[2]));
+ emit_move_insn (operands[0], temp);
+ DONE;
+ }
+}")
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=d,a,a,da,x,&!da")
+ (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,da")
+ (match_operand:SI 2 "nonmemory_operand" "J,J,L,dai,i,da")))]
+ ""
+ "@
+ inc %0
+ inc %0
+ inc4 %0
+ add %2,%0
+ add %2,%0
+ mov %2,%0\;add %1,%0"
+ [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
+
+;; ----------------------------------------------------------------------
+;; SUBTRACT INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "subsi3"
+ [(set (match_operand:SI 0 "register_operand" "=da")
+ (minus:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "nonmemory_operand" "dai")))]
+ ""
+ "sub %2,%0"
+ [(set_attr "cc" "set_zn")])
+
+(define_expand "negsi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (neg:SI (match_operand:SI 1 "register_operand" "")))]
+ ""
+ "
+{
+ rtx target = gen_reg_rtx (SImode);
+
+ emit_move_insn (target, GEN_INT (0));
+ emit_insn (gen_subsi3 (target, target, operands[1]));
+ emit_move_insn (operands[0], target);
+ DONE;
+}")
+
+;; ----------------------------------------------------------------------
+;; MULTIPLY INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "mulsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (mult:SI (match_operand:SI 1 "register_operand" "%0")
+ (match_operand:SI 2 "register_operand" "d")))]
+ ""
+ "*
+{
+ if (TARGET_MULT_BUG)
+ return \"nop\;nop\;mul %2,%0\";
+ else
+ return \"mul %2,%0\";
+}"
+ [(set_attr "cc" "set_zn")])
+
+(define_insn "udivmodsi4"
+ [(set (match_operand:SI 0 "general_operand" "=d")
+ (udiv:SI (match_operand:SI 1 "general_operand" "0")
+ (match_operand:SI 2 "general_operand" "d")))
+ (set (match_operand:SI 3 "general_operand" "=&d")
+ (umod:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "*
+{
+ if (zero_dreg)
+ output_asm_insn (\"mov %0,mdr\", &zero_dreg);
+ else
+ output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
+
+ if (find_reg_note (insn, REG_UNUSED, operands[3]))
+ return \"divu %2,%0\";
+ else
+ return \"divu %2,%0\;mov mdr,%3\";
+}"
+ [(set_attr "cc" "set_zn")])
+
+(define_insn "divmodsi4"
+ [(set (match_operand:SI 0 "general_operand" "=d")
+ (div:SI (match_operand:SI 1 "general_operand" "0")
+ (match_operand:SI 2 "general_operand" "d")))
+ (set (match_operand:SI 3 "general_operand" "=d")
+ (mod:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "*
+{
+ if (find_reg_note (insn, REG_UNUSED, operands[3]))
+ return \"ext %0\;div %2,%0\";
+ else
+ return \"ext %0\;div %2,%0\;mov mdr,%3\";
+}"
+ [(set_attr "cc" "set_zn")])
+
+
+;; ----------------------------------------------------------------------
+;; AND INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "andsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (and:SI (match_operand:SI 1 "register_operand" "%0,0")
+ (match_operand:SI 2 "nonmemory_operand" "N,di")))]
+ ""
+ "*
+{
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
+ return \"extbu %0\";
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
+ return \"exthu %0\";
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
+ return \"add %0,%0\;lsr 1,%0\";
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
+ return \"asl2 %0\;lsr 2,%0\";
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
+ return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
+ return \"asl2 %0,%0\;asl2 %0\;lsr 4,%0\";
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
+ return \"lsr 1,%0\;add %0,%0\";
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
+ return \"lsr 2,%0\;asl2 %0\";
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
+ return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
+ return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
+ return \"and %2,%0\";
+}"
+ [(set_attr "cc" "none_0hit,set_znv")])
+
+;; ----------------------------------------------------------------------
+;; OR INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "iorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (ior:SI (match_operand:SI 1 "register_operand" "%0")
+ (match_operand:SI 2 "nonmemory_operand" "di")))]
+ ""
+ "or %2,%0"
+ [(set_attr "cc" "set_znv")])
+
+;; ----------------------------------------------------------------------
+;; XOR INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "xorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (xor:SI (match_operand:SI 1 "register_operand" "%0")
+ (match_operand:SI 2 "nonmemory_operand" "di")))]
+ ""
+ "xor %2,%0"
+ [(set_attr "cc" "set_znv")])
+
+;; ----------------------------------------------------------------------
+;; NOT INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "one_cmplsi2"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (not:SI (match_operand:SI 1 "register_operand" "0")))]
+ ""
+ "not %0"
+ [(set_attr "cc" "set_znv")])
+
+;; -----------------------------------------------------------------
+;; BIT FIELDS
+;; -----------------------------------------------------------------
+
+
+;; These set/clear memory in byte sized chunks.
+;;
+;; They are no smaller/faster than loading the value into a register
+;; and storing the register, but they don't need a scratch register
+;; which may allow for better code generation.
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int 0))]
+ ""
+ "@
+ bclr 255,%A0
+ clr %0"
+ [(set_attr "cc" "clobber")])
+
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int -1))]
+ ""
+ "@
+ bset 255,%A0
+ mov -1,%0"
+ [(set_attr "cc" "clobber,none_0hit")])
+
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=R,d")
+ (subreg:QI
+ (and:SI (subreg:SI (match_dup 0) 0)
+ (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
+ ""
+ "@
+ bclr %N1,%A0
+ and %1,%0"
+ [(set_attr "cc" "clobber,set_znv")])
+
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=R,d")
+ (subreg:QI
+ (ior:SI (subreg:SI (match_dup 0) 0)
+ (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
+ ""
+ "@
+ bset %1,%A0
+ or %1,%0"
+ [(set_attr "cc" "clobber,set_znv")])
+
+(define_insn ""
+ [(set (cc0)
+ (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
+ (match_operand 1 "const_int_operand" "")
+ (match_operand 2 "const_int_operand" "")))]
+ ""
+ "*
+{
+ int len = INTVAL (operands[1]);
+ int bit = INTVAL (operands[2]);
+ int mask = 0;
+ rtx xoperands[2];
+
+ while (len > 0)
+ {
+ mask |= (1 << bit);
+ bit++;
+ len--;
+ }
+
+ xoperands[0] = operands[0];
+ xoperands[1] = GEN_INT (mask);
+ output_asm_insn (\"btst %1,%0\", xoperands);
+ return \"\";
+}"
+ [(set_attr "cc" "set_znv")])
+
+(define_insn ""
+ [(set (cc0)
+ (zero_extract:SI (match_operand:QI 0 "general_operand" "R,d")
+ (match_operand 1 "const_int_operand" "")
+ (match_operand 2 "const_int_operand" "")))]
+ "INTVAL (operands[1]) <= 8 && INTVAL (operands[2]) <= 7"
+ "*
+{
+ int len = INTVAL (operands[1]);
+ int bit = INTVAL (operands[2]);
+ int mask = 0;
+ rtx xoperands[2];
+
+ while (len > 0)
+ {
+ mask |= (1 << bit);
+ bit++;
+ len--;
+ }
+
+ xoperands[0] = operands[0];
+ xoperands[1] = GEN_INT (mask);
+ if (GET_CODE (operands[0]) == REG)
+ output_asm_insn (\"btst %1,%0\", xoperands);
+ else
+ output_asm_insn (\"btst %1,%A0\", xoperands);
+ return \"\";
+}"
+ [(set_attr "cc" "set_znv")])
+
+(define_insn ""
+ [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "d")
+ (match_operand:SI 1 "const_int_operand" "")))]
+ ""
+ "btst %1,%0"
+ [(set_attr "cc" "set_znv")])
+
+(define_insn ""
+ [(set (cc0)
+ (and:SI
+ (subreg:SI (match_operand:QI 0 "general_operand" "R,d") 0)
+ (match_operand:SI 1 "const_int_operand" "")))]
+ ""
+ "@
+ btst %1,%A0
+ btst %1,%0"
+ [(set_attr "cc" "set_znv")])
+
+
+;; ----------------------------------------------------------------------
+;; JUMP INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+;; Conditional jump instructions
+
+(define_expand "ble"
+ [(set (pc)
+ (if_then_else (le (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bleu"
+ [(set (pc)
+ (if_then_else (leu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bge"
+ [(set (pc)
+ (if_then_else (ge (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bgeu"
+ [(set (pc)
+ (if_then_else (geu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "blt"
+ [(set (pc)
+ (if_then_else (lt (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bltu"
+ [(set (pc)
+ (if_then_else (ltu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bgt"
+ [(set (pc)
+ (if_then_else (gt (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bgtu"
+ [(set (pc)
+ (if_then_else (gtu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "beq"
+ [(set (pc)
+ (if_then_else (eq (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bne"
+ [(set (pc)
+ (if_then_else (ne (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (match_operator 1 "comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
+ && (GET_CODE (operands[1]) == GT
+ || GET_CODE (operands[1]) == GE
+ || GET_CODE (operands[1]) == LE
+ || GET_CODE (operands[1]) == LT))
+ return 0;
+ return \"b%b1 %0\";
+}"
+ [(set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (match_operator 1 "comparison_operator"
+ [(cc0) (const_int 0)])
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
+ && (GET_CODE (operands[1]) == GT
+ || GET_CODE (operands[1]) == GE
+ || GET_CODE (operands[1]) == LE
+ || GET_CODE (operands[1]) == LT))
+ return 0;
+ return \"b%B1 %0\";
+}"
+ [(set_attr "cc" "none")])
+
+;; Unconditional and other jump instructions.
+
+(define_insn "jump"
+ [(set (pc)
+ (label_ref (match_operand 0 "" "")))]
+ ""
+ "jmp %l0"
+ [(set_attr "cc" "none")])
+
+(define_insn "indirect_jump"
+ [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
+ ""
+ "jmp (%0)"
+ [(set_attr "cc" "none")])
+
+(define_insn "tablejump"
+ [(set (pc) (match_operand:SI 0 "register_operand" "a"))
+ (use (label_ref (match_operand 1 "" "")))]
+ ""
+ "jmp (%0)"
+ [(set_attr "cc" "none")])
+
+;; Call subroutine with no return value.
+
+(define_expand "call"
+ [(call (match_operand:QI 0 "general_operand" "")
+ (match_operand:SI 1 "general_operand" ""))]
+ ""
+ "
+{
+ if (! call_address_operand (XEXP (operands[0], 0)))
+ XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
+ emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
+ DONE;
+}")
+
+(define_insn "call_internal"
+ [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
+ (match_operand:SI 1 "general_operand" "g"))]
+ ""
+ "*
+{
+ if (REG_P (operands[0]))
+ return \"calls %C0\";
+ else
+ return \"call %C0,[],0\";
+}"
+ [(set_attr "cc" "clobber")])
+
+;; Call subroutine, returning value in operand 0
+;; (which must be a hard register).
+
+(define_expand "call_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ ""
+ "
+{
+ if (! call_address_operand (XEXP (operands[1], 0)))
+ XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
+ emit_call_insn (gen_call_value_internal (operands[0],
+ XEXP (operands[1], 0),
+ operands[2]));
+ DONE;
+}")
+
+(define_insn "call_value_internal"
+ [(set (match_operand 0 "" "=da")
+ (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
+ (match_operand:SI 2 "general_operand" "g")))]
+ ""
+ "*
+{
+ if (REG_P (operands[1]))
+ return \"calls %C1\";
+ else
+ return \"call %C1,[],0\";
+}"
+ [(set_attr "cc" "clobber")])
+
+(define_expand "untyped_call"
+ [(parallel [(call (match_operand 0 "" "")
+ (const_int 0))
+ (match_operand 1 "" "")
+ (match_operand 2 "" "")])]
+ ""
+ "
+{
+ int i;
+
+ emit_call_insn (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));
+ }
+ DONE;
+}")
+
+(define_insn "nop"
+ [(const_int 0)]
+ ""
+ "nop"
+ [(set_attr "cc" "none")])
+
+;; ----------------------------------------------------------------------
+;; EXTEND INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "zero_extendqisi2"
+ [(set (match_operand:SI 0 "general_operand" "=d,d,d")
+ (zero_extend:SI
+ (match_operand:QI 1 "general_operand" "0,d,m")))]
+ ""
+ "@
+ extbu %0
+ mov %1,%0\;extbu %0
+ movbu %1,%0"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn "zero_extendhisi2"
+ [(set (match_operand:SI 0 "general_operand" "=d,d,d")
+ (zero_extend:SI
+ (match_operand:HI 1 "general_operand" "0,d,m")))]
+ ""
+ "@
+ exthu %0
+ mov %1,%0\;exthu %0
+ movhu %1,%0"
+ [(set_attr "cc" "none_0hit")])
+
+;;- sign extension instructions
+
+(define_insn "extendqisi2"
+ [(set (match_operand:SI 0 "general_operand" "=d,d")
+ (sign_extend:SI
+ (match_operand:QI 1 "general_operand" "0,d")))]
+ ""
+ "@
+ extb %0
+ mov %1,%0\;extb %0"
+ [(set_attr "cc" "none_0hit")])
+
+(define_insn "extendhisi2"
+ [(set (match_operand:SI 0 "general_operand" "=d,d")
+ (sign_extend:SI
+ (match_operand:HI 1 "general_operand" "0,d")))]
+ ""
+ "@
+ exth %0
+ mov %1,%0\;exth %0"
+ [(set_attr "cc" "none_0hit")])
+
+;; ----------------------------------------------------------------------
+;; SHIFTS
+;; ----------------------------------------------------------------------
+
+(define_insn "ashlsi3"
+ [(set (match_operand:SI 0 "register_operand" "=da,d,d,d,d")
+ (ashift:SI
+ (match_operand:SI 1 "register_operand" "0,0,0,0,0")
+ (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,di")))]
+ ""
+ "@
+ add %0,%0
+ asl2 %0
+ asl2 %0\;add %0,%0
+ asl2 %0\;asl2 %0
+ asl %S2,%0"
+ [(set_attr "cc" "set_zn")])
+
+(define_insn "lshrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (lshiftrt:SI
+ (match_operand:SI 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "di")))]
+ ""
+ "lsr %S2,%0"
+ [(set_attr "cc" "set_zn")])
+
+(define_insn "ashrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (ashiftrt:SI
+ (match_operand:SI 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "di")))]
+ ""
+ "asr %S2,%0"
+ [(set_attr "cc" "set_zn")])
+
+;; ----------------------------------------------------------------------
+;; PROLOGUE/EPILOGUE
+;; ----------------------------------------------------------------------
+(define_expand "prologue"
+ [(const_int 0)]
+ ""
+ "expand_prologue (); DONE;")
+
+(define_expand "epilogue"
+ [(return)]
+ ""
+ "
+{
+ expand_epilogue ();
+ DONE;
+}")
+
+(define_insn "return_internal"
+ [(const_int 2)]
+ ""
+ "rets"
+ [(set_attr "cc" "clobber")])
+
+;; This insn restores the callee saved registers and does a return, it
+;; can also deallocate stack space.
+(define_insn "return_internal_regs"
+ [(const_int 0)
+ (match_operand:SI 0 "const_int_operand" "i")
+ (return)]
+ ""
+ "ret [d2,d3,a2,a3],%0"
+ [(set_attr "cc" "clobber")])
+
+(define_insn "store_movm"
+ [(const_int 1)]
+ ""
+ "movm [d2,d3,a2,a3],(sp)"
+ [(set_attr "cc" "clobber")])
+
+(define_insn "return"
+ [(return)]
+ "can_use_return_insn ()"
+ "*
+{
+ rtx next = next_active_insn (insn);
+
+ if (next
+ && GET_CODE (next) == JUMP_INSN
+ && GET_CODE (PATTERN (next)) == RETURN)
+ return \"\";
+ else
+ return \"rets\";
+}"
+ [(set_attr "cc" "clobber")])
+
+;; Try to combine consecutive updates of the stack pointer (or any
+;; other register for that matter).
+(define_peephole
+ [(set (match_operand:SI 0 "register_operand" "=dax")
+ (plus:SI (match_dup 0)
+ (match_operand 1 "const_int_operand" "")))
+ (set (match_dup 0)
+ (plus:SI (match_dup 0)
+ (match_operand 2 "const_int_operand" "")))]
+ ""
+ "*
+{
+ operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
+ return \"add %1,%0\";
+}"
+ [(set_attr "cc" "clobber")])
+
+;;
+;; We had patterns to check eq/ne, but the they don't work because
+;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
+;;
+;; The Z flag and C flag would be set, and we have no way to
+;; check for the Z flag set and C flag clear.
+;;
+;; This will work on the mn10200 because we can check the ZX flag
+;; if the comparison is in HImode.
+(define_peephole
+ [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
+ (set (pc) (if_then_else (ge (cc0) (const_int 0))
+ (match_operand 1 "" "")
+ (pc)))]
+ "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
+ "add %0,%0\;bcc %1"
+ [(set_attr "cc" "clobber")])
+
+(define_peephole
+ [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
+ (set (pc) (if_then_else (lt (cc0) (const_int 0))
+ (match_operand 1 "" "")
+ (pc)))]
+ "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
+ "add %0,%0\;bcs %1"
+ [(set_attr "cc" "clobber")])
+
+(define_peephole
+ [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
+ (set (pc) (if_then_else (ge (cc0) (const_int 0))
+ (pc)
+ (match_operand 1 "" "")))]
+ "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
+ "add %0,%0\;bcs %1"
+ [(set_attr "cc" "clobber")])
+
+(define_peephole
+ [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
+ (set (pc) (if_then_else (lt (cc0) (const_int 0))
+ (pc)
+ (match_operand 1 "" "")))]
+ "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
+ "add %0,%0\;bcc %1"
+ [(set_attr "cc" "clobber")])
+
diff --git a/gnu/usr.bin/gcc/config/mn10300/t-mn10300 b/gnu/usr.bin/gcc/config/mn10300/t-mn10300
new file mode 100644
index 00000000000..379b90fca7f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10300/t-mn10300
@@ -0,0 +1,20 @@
+LIBGCC1=libgcc1.null
+CROSS_LIBGCC1=libgcc1.null
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so...
+
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#ifdef __LITTLE_ENDIAN__' > dp-bit.c
+ echo '#define FLOAT_BIT_ORDER_MISMATCH' >>dp-bit.c
+ echo '#endif' >> dp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ echo '#ifdef __LITTLE_ENDIAN__' >> fp-bit.c
+ echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c
+ echo '#endif' >> fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
diff --git a/gnu/usr.bin/gcc/config/mn10300/xm-mn10300.h b/gnu/usr.bin/gcc/config/mn10300/xm-mn10300.h
new file mode 100644
index 00000000000..63d61c276c2
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/mn10300/xm-mn10300.h
@@ -0,0 +1,47 @@
+/* Configuration for Matsushita MN10300.
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+
+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 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"
+
+#ifndef __STDC__
+extern char *malloc (), *realloc (), *calloc ();
+#else
+extern void *malloc (), *realloc (), *calloc ();
+#endif
+extern void free ();
diff --git a/gnu/usr.bin/gcc/config/pa/ee.asm b/gnu/usr.bin/gcc/config/pa/ee.asm
new file mode 100644
index 00000000000..787bda75c0d
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/pa/ee.asm
@@ -0,0 +1,261 @@
+; Subroutines for out of line prologues and epilogues on for the HPPA
+; Copyright (C) 1994, 1995, 1996 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.
+
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .SUBSPA $MILLICODE$,QUAD=0,ALIGN=8,ACCESS=44,SORT=8
+
+; This is an out-of-line prologue.
+;
+; It performs the following operations:
+;
+; * Saves the return pointer at sp - 20
+;
+; * Creates a new stack frame (sp'), size of the frame is passed in %r21
+;
+; * The old stack pointer is saved at sp (frame pointer version only).
+;
+; * Saves grs (passed in low 16 bits of %r22 into the stack frame
+; at sp' + local_fsize (passed in %r19).
+;
+; * Saves frs (passed in high 16 bits of %r22) into the stack
+; frame at sp' + local_fsize (passed in %r19).
+;
+; * Sets up a frame pointer (in %r3) (frame pointer version only).
+;
+; * Returns to the instruction _immediately_ after the call to
+; this function.
+
+ .SPACE $TEXT$
+ .SUBSPA $MILLICODE$
+ .EXPORT __outline_prologue,MILLICODE
+ .align 32
+__outline_prologue
+ .PROC
+ .CALLINFO FRAME=0,NO_CALLS
+ .ENTRY
+ copy %r30,%r20
+
+ ; Subtract 4 from our return pointer so that we return to
+ ; the right location.
+ ldo -4(%r31),%r31
+
+ ; Save off %r2
+ stw %r2,-20(0,%r30)
+
+ ; Make our new frame.
+ add %r21,%r30,%r30
+
+ ; Add in local_fsize to our frame pointer so we do register
+ ; saves into the right place
+ add %r20,%r19,%r20
+
+ ; %r22 tells us what registers we need to save. The upper half
+ ; is for fp registers, the lower half for integer registers.
+ ; We put the lower half in %r1 and the upper half into %r22
+ ; for later use.
+ extru %r22,31,16,%r1
+ extrs %r22,15,16,%r22
+
+ ; %r1 now olds a value 0-18 which corresponds to the number
+ ; of grs we need to save. We need to reverse that value so
+ ; we can just into the table and straight-line execute to the
+ ; end of the gr saves.
+ comb,= %r0,%r1,L$0000
+ subi 18,%r1,%r1
+ blr,n %r1,%r0
+ b,n L$0000
+ stws,ma %r18,4(0,%r20)
+ nop
+ stws,ma %r17,4(0,%r20)
+ nop
+ stws,ma %r16,4(0,%r20)
+ nop
+ stws,ma %r15,4(0,%r20)
+ nop
+ stws,ma %r14,4(0,%r20)
+ nop
+ stws,ma %r13,4(0,%r20)
+ nop
+ stws,ma %r12,4(0,%r20)
+ nop
+ stws,ma %r11,4(0,%r20)
+ nop
+ stws,ma %r10,4(0,%r20)
+ nop
+ stws,ma %r9,4(0,%r20)
+ nop
+ stws,ma %r8,4(0,%r20)
+ nop
+ stws,ma %r7,4(0,%r20)
+ nop
+ stws,ma %r6,4(0,%r20)
+ nop
+ stws,ma %r5,4(0,%r20)
+ nop
+ stws,ma %r4,4(0,%r20)
+ nop
+ stws,ma %r3,4(0,%r20)
+ nop
+L$0000
+ ; All gr saves are done. Align the temporary frame pointer and
+ ; do the fr saves.
+ ldo 7(%r20),%r20
+ depi 0,31,3,%r20
+
+ comb,= %r0,%r22,L$0001
+ subi 21,%r22,%r22
+ blr,n %r22,%r0
+ b,n L$0001
+ fstws,ma %fr21,8(0,%r20)
+ nop
+ fstws,ma %fr20,8(0,%r20)
+ nop
+ fstws,ma %fr19,8(0,%r20)
+ nop
+ fstws,ma %fr18,8(0,%r20)
+ nop
+ fstws,ma %fr17,8(0,%r20)
+ nop
+ fstws,ma %fr16,8(0,%r20)
+ nop
+ fstws,ma %fr15,8(0,%r20)
+ nop
+ fstws,ma %fr14,8(0,%r20)
+ nop
+ fstws,ma %fr13,8(0,%r20)
+ nop
+ fstws,ma %fr12,8(0,%r20)
+ nop
+L$0001
+ ; Return
+ bv,n 0(%r31)
+ .EXIT
+ .PROCEND
+
+
+
+ .EXPORT __outline_epilogue,MILLICODE
+ .align 32
+__outline_epilogue
+ .PROC
+ .CALLINFO FRAME=0,NO_CALLS
+ .ENTRY
+ ; Get our original stack pointer and put it in %r20
+ sub %r30,%r21,%r20
+
+ ; Subtract 4 from our return pointer so that we return to
+ ; the right location.
+ ldo -4(%r31),%r31
+
+ ; Reload %r2
+ ldw -20(0,%r20),%r2
+
+ ; Add in local_fsize (%r19) to the frame pointer to find
+ ; the saved registers.
+ add %r20,%r19,%r20
+
+ ; %r22 tells us what registers we need to restore. The upper half
+ ; is for fp registers, the lower half for integer registers.
+ ; We put the lower half in %r1 and the upper half into %r22
+ ; for later use.
+ extru %r22,31,16,%r1
+ extrs %r22,15,16,%r22
+
+ ; %r1 now olds a value 0-18 which corresponds to the number
+ ; of grs we need to restore. We need to reverse that value so
+ ; we can just into the table and straight-line execute to the
+ ; end of the gr restore.
+ comb,= %r0,%r1,L$0004
+ subi 18,%r1,%r1
+ blr,n %r1,%r0
+ b,n L$0004
+ ldws,ma 4(0,%r20),%r18
+ nop
+ ldws,ma 4(0,%r20),%r17
+ nop
+ ldws,ma 4(0,%r20),%r16
+ nop
+ ldws,ma 4(0,%r20),%r15
+ nop
+ ldws,ma 4(0,%r20),%r14
+ nop
+ ldws,ma 4(0,%r20),%r13
+ nop
+ ldws,ma 4(0,%r20),%r12
+ nop
+ ldws,ma 4(0,%r20),%r11
+ nop
+ ldws,ma 4(0,%r20),%r10
+ nop
+ ldws,ma 4(0,%r20),%r9
+ nop
+ ldws,ma 4(0,%r20),%r8
+ nop
+ ldws,ma 4(0,%r20),%r7
+ nop
+ ldws,ma 4(0,%r20),%r6
+ nop
+ ldws,ma 4(0,%r20),%r5
+ nop
+ ldws,ma 4(0,%r20),%r4
+ nop
+ ldws,ma 4(0,%r20),%r3
+ nop
+L$0004
+ ; All gr restore are done. Align the temporary frame pointer and
+ ; do the fr restore.
+ ldo 7(%r20),%r20
+ depi 0,31,3,%r20
+
+ comb,= %r0,%r22,L$0005
+ subi 21,%r22,%r22
+ blr,n %r22,%r0
+ b,n L$0005
+ fldws,ma 8(0,%r20),%fr21
+ nop
+ fldws,ma 8(0,%r20),%fr20
+ nop
+ fldws,ma 8(0,%r20),%fr19
+ nop
+ fldws,ma 8(0,%r20),%fr18
+ nop
+ fldws,ma 8(0,%r20),%fr17
+ nop
+ fldws,ma 8(0,%r20),%fr16
+ nop
+ fldws,ma 8(0,%r20),%fr15
+ nop
+ fldws,ma 8(0,%r20),%fr14
+ nop
+ fldws,ma 8(0,%r20),%fr13
+ nop
+ fldws,ma 8(0,%r20),%fr12
+ nop
+L$0005
+ ; Return and deallocate our frame.
+ bv 0(%r31)
+ sub %r30,%r21,%r30
+ .EXIT
+ .PROCEND
diff --git a/gnu/usr.bin/gcc/config/pa/ee_fp.asm b/gnu/usr.bin/gcc/config/pa/ee_fp.asm
new file mode 100644
index 00000000000..ef040cf7dad
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/pa/ee_fp.asm
@@ -0,0 +1,274 @@
+; Subroutines for out of line prologues and epilogues on for the HPPA
+; Copyright (C) 1994, 1995, 1996 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.
+
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .SUBSPA $MILLICODE$,QUAD=0,ALIGN=8,ACCESS=44,SORT=8
+
+
+; This is an out-of-line prologue.
+;
+; It performs the following operations:
+;
+; * Saves the return pointer at sp - 20
+;
+; * Creates a new stack frame (sp'), size of the frame is passed in %r21
+;
+; * The old stack pointer is saved at sp (frame pointer version only).
+;
+; * Saves grs (passed in low 16 bits of %r22 into the stack frame
+; at sp' + local_fsize (passed in %r19).
+;
+; * Saves frs (passed in high 16 bits of %r22) into the stack
+; frame at sp' + local_fsize (passed in %r19).
+;
+; * Sets up a frame pointer (in %r3) (frame pointer version only).
+;
+; * Returns to the instruction _immediately_ after the call to
+; this function.
+
+ .SPACE $TEXT$
+ .SUBSPA $MILLICODE$
+ .EXPORT __outline_prologue_fp,MILLICODE
+ .align 32
+__outline_prologue_fp
+ .PROC
+ .CALLINFO FRAME=0,NO_CALLS
+ .ENTRY
+ copy %r30,%r20
+
+ ; Subtract 4 from our return pointer so that we return to
+ ; the right location.
+ ldo -4(%r31),%r31
+
+ ; Save off %r2
+ stw %r2,-20(0,%r30)
+
+ ; Make our new frame.
+ add %r21,%r30,%r30
+
+ ; Save our old stack pointer.
+ stw %r20,0(0,%r20)
+
+ ; Add in local_fsize to our frame pointer so we do register
+ ; saves into the right place
+ add %r20,%r19,%r20
+
+ ; %r22 tells us what registers we need to save. The upper half
+ ; is for fp registers, the lower half for integer registers.
+ ; We put the lower half in %r1 and the upper half into %r22
+ ; for later use.
+ extru %r22,31,16,%r1
+ extrs %r22,15,16,%r22
+
+ ; %r1 now olds a value 0-18 which corresponds to the number
+ ; of grs we need to save. We need to reverse that value so
+ ; we can just into the table and straight-line execute to the
+ ; end of the gr saves.
+ comb,= %r0,%r1,L$0002
+ subi 18,%r1,%r1
+ blr,n %r1,%r0
+ b,n L$0002
+ stws,ma %r18,4(0,%r20)
+ nop
+ stws,ma %r17,4(0,%r20)
+ nop
+ stws,ma %r16,4(0,%r20)
+ nop
+ stws,ma %r15,4(0,%r20)
+ nop
+ stws,ma %r14,4(0,%r20)
+ nop
+ stws,ma %r13,4(0,%r20)
+ nop
+ stws,ma %r12,4(0,%r20)
+ nop
+ stws,ma %r11,4(0,%r20)
+ nop
+ stws,ma %r10,4(0,%r20)
+ nop
+ stws,ma %r9,4(0,%r20)
+ nop
+ stws,ma %r8,4(0,%r20)
+ nop
+ stws,ma %r7,4(0,%r20)
+ nop
+ stws,ma %r6,4(0,%r20)
+ nop
+ stws,ma %r5,4(0,%r20)
+ nop
+ stws,ma %r4,4(0,%r20)
+ nop
+ stws,ma %r3,4(0,%r20)
+ nop
+L$0002
+ ; All gr saves are done. Align the temporary frame pointer and
+ ; do the fr saves.
+ ldo 7(%r20),%r20
+ depi 0,31,3,%r20
+
+ comb,= %r0,%r22,L$0003
+ subi 21,%r22,%r22
+ blr,n %r22,%r0
+ b,n L$0003
+ fstws,ma %fr21,8(0,%r20)
+ nop
+ fstws,ma %fr20,8(0,%r20)
+ nop
+ fstws,ma %fr19,8(0,%r20)
+ nop
+ fstws,ma %fr18,8(0,%r20)
+ nop
+ fstws,ma %fr17,8(0,%r20)
+ nop
+ fstws,ma %fr16,8(0,%r20)
+ nop
+ fstws,ma %fr15,8(0,%r20)
+ nop
+ fstws,ma %fr14,8(0,%r20)
+ nop
+ fstws,ma %fr13,8(0,%r20)
+ nop
+ fstws,ma %fr12,8(0,%r20)
+ nop
+L$0003
+ ; Return, setting up a frame pointer in the delay slot
+ bv 0(%r31)
+ sub %r30,%r21,%r3
+ .EXIT
+ .PROCEND
+
+
+; This is an out-of-line epilogue. It's operation is basically the reverse
+; of the out-of-line prologue.
+
+ .EXPORT __outline_epilogue_fp,MILLICODE
+ .align 32
+__outline_epilogue_fp
+ .PROC
+ .CALLINFO FRAME=0,NO_CALLS
+ .ENTRY
+ ; Make a copy of our frame pointer into %r20
+ copy %r3,%r20
+
+ ; Subtract 4 from our return pointer so that we return to
+ ; the right location.
+ ldo -4(%r31),%r31
+
+ ; Reload %r2
+ ; First save off %r2
+ ldw -20(0,%r20),%r2
+
+ ; Load our old stack pointer, save it in %r21.
+ ldw 0(0,%r20),%r21
+
+ ; Add in local_fsize (%r19) to the frame pointer to find
+ ; the saved registers.
+ add %r20,%r19,%r20
+
+ ; %r22 tells us what registers we need to restore. The upper half
+ ; is for fp registers, the lower half for integer registers.
+ ; We put the lower half in %r1 and the upper half into %r22
+ ; for later use.
+ extru %r22,31,16,%r1
+ extrs %r22,15,16,%r22
+
+ ; %r1 now olds a value 0-18 which corresponds to the number
+ ; of grs we need to restore. We need to reverse that value so
+ ; we can just into the table and straight-line execute to the
+ ; end of the gr restore.
+ comb,= %r0,%r1,L$0006
+ subi 18,%r1,%r1
+ blr,n %r1,%r0
+ b,n L$0006
+ ldws,ma 4(0,%r20),%r18
+ nop
+ ldws,ma 4(0,%r20),%r17
+ nop
+ ldws,ma 4(0,%r20),%r16
+ nop
+ ldws,ma 4(0,%r20),%r15
+ nop
+ ldws,ma 4(0,%r20),%r14
+ nop
+ ldws,ma 4(0,%r20),%r13
+ nop
+ ldws,ma 4(0,%r20),%r12
+ nop
+ ldws,ma 4(0,%r20),%r11
+ nop
+ ldws,ma 4(0,%r20),%r10
+ nop
+ ldws,ma 4(0,%r20),%r9
+ nop
+ ldws,ma 4(0,%r20),%r8
+ nop
+ ldws,ma 4(0,%r20),%r7
+ nop
+ ldws,ma 4(0,%r20),%r6
+ nop
+ ldws,ma 4(0,%r20),%r5
+ nop
+ ldws,ma 4(0,%r20),%r4
+ nop
+ ldws,ma 4(0,%r20),%r3
+ nop
+L$0006
+ ; All gr restore are done. Align the temporary frame pointer and
+ ; do the fr restore.
+ ldo 7(%r20),%r20
+ depi 0,31,3,%r20
+
+ comb,= %r0,%r22,L$0007
+ subi 21,%r22,%r22
+ blr,n %r22,%r0
+ b,n L$0007
+ fldws,ma 8(0,%r20),%fr21
+ nop
+ fldws,ma 8(0,%r20),%fr20
+ nop
+ fldws,ma 8(0,%r20),%fr19
+ nop
+ fldws,ma 8(0,%r20),%fr18
+ nop
+ fldws,ma 8(0,%r20),%fr17
+ nop
+ fldws,ma 8(0,%r20),%fr16
+ nop
+ fldws,ma 8(0,%r20),%fr15
+ nop
+ fldws,ma 8(0,%r20),%fr14
+ nop
+ fldws,ma 8(0,%r20),%fr13
+ nop
+ fldws,ma 8(0,%r20),%fr12
+ nop
+L$0007
+ ; Return and deallocate our frame.
+ bv 0(%r31)
+ copy %r21,%r30
+ .EXIT
+ .PROCEND
+
+
diff --git a/gnu/usr.bin/gcc/config/pa/lib1funcs.asm b/gnu/usr.bin/gcc/config/pa/lib1funcs.asm
new file mode 100644
index 00000000000..95eb75e1398
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/pa/lib1funcs.asm
@@ -0,0 +1,1146 @@
+; Low level integer divide, multiply, remainder, etc routines for the HPPA.
+; 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.
+
+; 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.)
+
+; 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.
+
+#ifdef L_dyncall
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .export $$dyncall
+$$dyncall
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ bb,>=,n %r22,30,L$1 ; branch if not plabel address
+ depi 0,31,2,%r22 ; clear the two least significant bits
+ ldw 4(%sr0,%r22),%r19 ; load new LTP value
+ ldw 0(%sr0,%r22),%r22 ; load address of target
+L$1 ldsid (%sr0,%r22),%r1 ; get the "space ident" selected by r22
+ mtsp %r1,%sr0 ; move that space identifier into sr0
+ be 0(%sr0,%r22) ; branch to the real target
+ stw %r2,-24(%sr0,%r30) ; save return address into frame marker
+ .exit
+ .procend
+#endif
+
+
+#ifdef L_multiply
+#define op0 %r26
+#define op1 %r25
+#define res %r29
+#define ret %r31
+#define tmp %r1
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$mulU
+ .export $$mulI
+$$mulU
+$$mulI
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ addi,tr 0,%r0,res ; clear out res, skip next insn
+L$loop zdep op1,26,27,op1 ; shift up op1 by 5
+L$lo zdep op0,30,5,tmp ; extract next 5 bits and shift up
+ blr tmp,%r0
+ extru op0,26,27,op0 ; shift down op0 by 5
+L$0 comib,<> 0,op0,L$lo
+ zdep op1,26,27,op1 ; shift up op1 by 5
+ bv %r0(ret)
+ nop
+L$1 b L$loop
+ addl op1,res,res
+ nop
+ nop
+L$2 b L$loop
+ sh1addl op1,res,res
+ nop
+ nop
+L$3 sh1addl op1,op1,tmp ; 3x
+ b L$loop
+ addl tmp,res,res
+ nop
+L$4 b L$loop
+ sh2addl op1,res,res
+ nop
+ nop
+L$5 sh2addl op1,op1,tmp ; 5x
+ b L$loop
+ addl tmp,res,res
+ nop
+L$6 sh1addl op1,op1,tmp ; 3x
+ b L$loop
+ sh1addl tmp,res,res
+ nop
+L$7 zdep op1,28,29,tmp ; 8x
+ sub tmp,op1,tmp ; 7x
+ b L$loop
+ addl tmp,res,res
+L$8 b L$loop
+ sh3addl op1,res,res
+ nop
+ nop
+L$9 sh3addl op1,op1,tmp ; 9x
+ b L$loop
+ addl tmp,res,res
+ nop
+L$10 sh2addl op1,op1,tmp ; 5x
+ b L$loop
+ sh1addl tmp,res,res
+ nop
+L$11 sh2addl op1,op1,tmp ; 5x
+ sh1addl tmp,op1,tmp ; 11x
+ b L$loop
+ addl tmp,res,res
+L$12 sh1addl op1,op1,tmp ; 3x
+ b L$loop
+ sh2addl tmp,res,res
+ nop
+L$13 sh1addl op1,op1,tmp ; 3x
+ sh2addl tmp,op1,tmp ; 13x
+ b L$loop
+ addl tmp,res,res
+L$14 zdep op1,28,29,tmp ; 8x
+ sub tmp,op1,tmp ; 7x
+ b L$loop
+ sh1addl tmp,res,res
+L$15 zdep op1,27,28,tmp ; 16x
+ sub tmp,op1,tmp ; 15x
+ b L$loop
+ addl tmp,res,res
+L$16 zdep op1,27,28,tmp ; 16x
+ b L$loop
+ addl tmp,res,res
+ nop
+L$17 zdep op1,27,28,tmp ; 16x
+ addl tmp,op1,tmp ; 17x
+ b L$loop
+ addl tmp,res,res
+L$18 sh3addl op1,op1,tmp ; 9x
+ b L$loop
+ sh1addl tmp,res,res
+ nop
+L$19 sh3addl op1,op1,tmp ; 9x
+ sh1addl tmp,op1,tmp ; 19x
+ b L$loop
+ addl tmp,res,res
+L$20 sh2addl op1,op1,tmp ; 5x
+ b L$loop
+ sh2addl tmp,res,res
+ nop
+L$21 sh2addl op1,op1,tmp ; 5x
+ sh2addl tmp,op1,tmp ; 21x
+ b L$loop
+ addl tmp,res,res
+L$22 sh2addl op1,op1,tmp ; 5x
+ sh1addl tmp,op1,tmp ; 11x
+ b L$loop
+ sh1addl tmp,res,res
+L$23 sh1addl op1,op1,tmp ; 3x
+ sh3addl tmp,res,res ; += 8x3
+ b L$loop
+ sub res,op1,res ; -= x
+L$24 sh1addl op1,op1,tmp ; 3x
+ b L$loop
+ sh3addl tmp,res,res ; += 8x3
+ nop
+L$25 sh2addl op1,op1,tmp ; 5x
+ sh2addl tmp,tmp,tmp ; 25x
+ b L$loop
+ addl tmp,res,res
+L$26 sh1addl op1,op1,tmp ; 3x
+ sh2addl tmp,op1,tmp ; 13x
+ b L$loop
+ sh1addl tmp,res,res ; += 2x13
+L$27 sh1addl op1,op1,tmp ; 3x
+ sh3addl tmp,tmp,tmp ; 27x
+ b L$loop
+ addl tmp,res,res
+L$28 zdep op1,28,29,tmp ; 8x
+ sub tmp,op1,tmp ; 7x
+ b L$loop
+ sh2addl tmp,res,res ; += 4x7
+L$29 sh1addl op1,op1,tmp ; 3x
+ sub res,tmp,res ; -= 3x
+ b L$foo
+ zdep op1,26,27,tmp ; 32x
+L$30 zdep op1,27,28,tmp ; 16x
+ sub tmp,op1,tmp ; 15x
+ b L$loop
+ sh1addl tmp,res,res ; += 2x15
+L$31 zdep op1,26,27,tmp ; 32x
+ sub tmp,op1,tmp ; 31x
+L$foo b L$loop
+ addl tmp,res,res
+ .exit
+ .procend
+#endif
+
+
+#ifdef L_divU
+#define dividend %r26
+#define divisor %r25
+#define tmp %r1
+#define quotient %r29
+#define ret %r31
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU
+$$divU
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ comb,< divisor,0,L$largedivisor
+ sub %r0,divisor,%r1 ; clear cy as side-effect
+ ds %r0,%r1,%r0
+ addc dividend,dividend,dividend
+ ds %r0,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,quotient
+ ds %r1,divisor,%r1
+ bv 0(ret)
+ addc quotient,quotient,quotient
+L$largedivisor
+ comclr,<< dividend,divisor,quotient
+ ldi 1,quotient
+ bv,n 0(ret)
+ .exit
+ .procend
+#endif
+
+
+#ifdef L_remU
+#define dividend %r26
+#define divisor %r25
+#define quotient %r29
+#define tmp %r1
+#define ret %r31
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$remU
+$$remU
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ comb,< divisor,0,L$largedivisor
+ sub %r0,divisor,%r1 ; clear cy as side-effect
+ ds %r0,%r1,%r0
+ addc dividend,dividend,dividend
+ ds %r0,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,quotient
+ ds %r1,divisor,%r1
+ comclr,>= %r1,%r0,%r0
+ addl %r1,divisor,%r1
+ bv 0(ret)
+ copy %r1,quotient
+L$largedivisor
+ sub,>>= dividend,divisor,quotient
+ copy dividend,quotient
+ bv,n 0(ret)
+ .exit
+ .procend
+#endif
+
+
+#ifdef L_divI
+#define dividend %r26
+#define divisor %r25
+#define quotient %r29
+#define tmp %r1
+#define ret %r31
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divI
+$$divI
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ xor dividend,divisor,quotient ; result sign
+ comclr,>= divisor,%r0,%r0 ; get absolute values
+ sub %r0,divisor,divisor
+ comclr,>= dividend,%r0,%r0
+ sub %r0,dividend,dividend
+
+ comb,< divisor,0,L$largedivisor
+ sub %r0,divisor,%r1 ; clear cy as side-effect
+ ds %r0,%r1,%r0
+ addc dividend,dividend,dividend
+ ds %r0,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ comclr,>= %r1,%r0,%r0
+ addl %r1,divisor,%r1
+ comclr,>= quotient,%r0,%r0 ; skip of no need to negate
+ sub %r0,dividend,dividend
+ bv 0(ret)
+ copy dividend,quotient
+L$largedivisor
+ comclr,<< dividend,divisor,quotient
+ ldi 1,quotient
+ bv,n 0(ret)
+ .exit
+ .procend
+#endif
+
+
+#ifdef L_remI
+#define dividend %r26
+#define divisor %r25
+#define quotient %r29
+#define tmp %r1
+#define ret %r31
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$remI
+$$remI
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ xor dividend,%r0,quotient ; result sign
+ comclr,>= divisor,%r0,%r0 ; get absolute values
+ sub %r0,divisor,divisor
+ comclr,>= dividend,%r0,%r0
+ sub %r0,dividend,dividend
+
+ comb,< divisor,0,L$largedivisor
+ sub %r0,divisor,%r1 ; clear cy as side-effect
+ ds %r0,%r1,%r0
+ addc dividend,dividend,dividend
+ ds %r0,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ ds %r1,divisor,%r1
+ addc dividend,dividend,dividend
+ comclr,>= %r1,%r0,%r0
+ addl %r1,divisor,%r1
+ comclr,>= quotient,%r0,%r0 ; skip of no need to negate
+ sub %r0,%r1,%r1
+ bv 0(ret)
+ copy %r1,quotient
+L$largedivisor
+ sub,>>= dividend,divisor,quotient
+ copy dividend,quotient
+ bv,n 0(ret)
+ .exit
+ .procend
+#endif
+
+
+#if defined (L_divU_3) && !defined (SMALL_LIB)
+#undef L_divU_3
+#define dividend %r26
+#define divisor %r25
+#define tmp %r1
+#define result %r29
+#define ret %r31
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_3
+$$divU_3
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ sh2add %r26,%r26,%r29 ; r29 = lo(101 x r)
+ shd %r0,%r26,30,%r1 ; r1 = hi(100 x r)
+ addc %r1,%r0,%r1 ; r1 = hi(101 x r)
+; r in r1,,r29
+ zdep %r29,27,28,%r25 ; r25 = lo(10000 x r)
+ add %r25,%r29,%r25 ; r25 = lo(10001 x r)
+ shd %r1,%r29,28,%r29 ; r29 = hi(10000 x r)
+ addc %r29,%r1,%r29 ; r29 = hi(10001 x r)
+; r in r29,,r25
+ zdep %r25,23,24,%r1 ; r1 = lo(100000000 x r)
+ add %r1,%r25,%r1 ; r1 = lo(100000001 x r)
+ shd %r29,%r25,24,%r25 ; r25 = hi(100000000 x r)
+ addc %r25,%r29,%r25 ; r25 = hi(100000001 x r)
+; r in r25,,r1
+ zdep %r1,15,16,%r29
+ add %r29,%r1,%r29
+ shd %r25,%r1,16,%r1
+ addc %r1,%r25,%r1
+; r in r1,,r29
+ sh1add %r29,%r26,%r0 ; r0 = lo(10 x r) + dividend
+ shd %r1,%r29,31,%r29 ; r29 = hi(10 x r)
+ addc %r29,%r0,%r29
+ bv 0(ret)
+ extru %r29,30,31,result
+ .exit
+ .procend
+#endif
+
+
+#if defined (L_divU_5) && !defined (SMALL_LIB)
+#undef L_divU_5
+#define dividend %r26
+#define divisor %r25
+#define tmp %r1
+#define result %r29
+#define ret %r31
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_5
+$$divU_5
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ sh1add %r26,%r26,%r29 ; r29 = lo(11 x r)
+ shd %r0,%r26,31,%r1 ; r1 = hi(10 x r)
+ addc %r1,%r0,%r1 ; r1 = hi(11 x r)
+; r in r1,,r29
+ zdep %r29,27,28,%r25 ; r25 = lo(10000 x r)
+ add %r25,%r29,%r25 ; r25 = lo(10001 x r)
+ shd %r1,%r29,28,%r29 ; r29 = hi(10000 x r)
+ addc %r29,%r1,%r29 ; r29 = hi(10001 x r)
+; r in r29,,r25
+ zdep %r25,23,24,%r1 ; r1 = lo(100000000 x r)
+ add %r1,%r25,%r1 ; r1 = lo(100000001 x r)
+ shd %r29,%r25,24,%r25 ; r25 = hi(100000000 x r)
+ addc %r25,%r29,%r25 ; r25 = hi(100000001 x r)
+; r in r25,,r1
+ zdep %r1,15,16,%r29
+ add %r29,%r1,%r29
+ shd %r25,%r1,16,%r1
+ addc %r1,%r25,%r1
+; r in r1,,r29
+ sh2add %r29,%r26,%r0 ; r0 = lo(1000 x r) + dividend
+ shd %r1,%r29,30,%r29 ; r29 = hi(1000 x r)
+ addc %r29,%r0,%r29
+ bv 0(ret)
+ extru %r29,29,30,result
+ .exit
+ .procend
+#endif
+
+
+#if defined (L_divU_6) && !defined (SMALL_LIB)
+#undef L_divU_6
+#define dividend %r26
+#define divisor %r25
+#define tmp %r1
+#define result %r29
+#define ret %r31
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_6
+$$divU_6
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ sh2add %r26,%r26,%r29 ; r29 = lo(101 x r)
+ shd %r0,%r26,30,%r1 ; r1 = hi(100 x r)
+ addc %r1,%r0,%r1 ; r1 = hi(101 x r)
+; r in r1,,r29
+ zdep %r29,27,28,%r25 ; r25 = lo(10000 x r)
+ add %r25,%r29,%r25 ; r25 = lo(10001 x r)
+ shd %r1,%r29,28,%r29 ; r29 = hi(10000 x r)
+ addc %r29,%r1,%r29 ; r29 = hi(10001 x r)
+; r in r29,,r25
+ zdep %r25,23,24,%r1 ; r1 = lo(100000000 x r)
+ add %r1,%r25,%r1 ; r1 = lo(100000001 x r)
+ shd %r29,%r25,24,%r25 ; r25 = hi(100000000 x r)
+ addc %r25,%r29,%r25 ; r25 = hi(100000001 x r)
+; r in r25,,r1
+ zdep %r1,15,16,%r29
+ add %r29,%r1,%r29
+ shd %r25,%r1,16,%r1
+ addc %r1,%r25,%r1
+; r in r1,,r29
+ sh1add %r29,%r26,%r0 ; r0 = lo(10 x r) + dividend
+ shd %r1,%r29,31,%r29 ; r29 = hi(10 x r)
+ addc %r29,%r0,%r29
+ bv 0(ret)
+ extru %r29,29,30,result
+ .exit
+ .procend
+#endif
+
+
+#if defined (L_divU_9) && !defined (SMALL_LIB)
+#undef L_divU_9
+#define dividend %r26
+#define divisor %r25
+#define tmp %r1
+#define result %r29
+#define ret %r31
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_9
+$$divU_9
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ zdep %r26,28,29,%r29
+ sub %r29,%r26,%r29
+ shd 0,%r26,29,%r1
+ subb %r1,0,%r1 /* 111 */
+
+ zdep %r29,25,26,%r25
+ add %r25,%r29,%r25
+ shd %r1,%r29,26,%r29
+ addc %r29,%r1,%r29 /* 111000111 */
+
+ sh3add %r25,%r26,%r1
+ shd %r29,%r25,29,%r25
+ addc %r25,0,%r25 /* 111000111001 */
+
+ zdep %r1,16,17,%r29
+ sub %r29,%r1,%r29
+ shd %r25,%r1,17,%r1
+ subb %r1,%r25,%r1 /* 111000111000111000111000111 */
+
+ sh3add %r29,%r26,%r0
+ shd %r1,%r29,29,%r29
+ addc %r29,0,%r29 /* 111000111000111000111000111001 */
+ bv 0(ret)
+ extru %r29,30,31,result
+ .exit
+ .procend
+#endif
+
+
+#if defined (L_divU_10) && !defined (SMALL_LIB)
+#undef L_divU_10
+#define dividend %r26
+#define divisor %r25
+#define tmp %r1
+#define result %r29
+#define ret %r31
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_10
+$$divU_10
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ sh1add %r26,%r26,%r29 ; r29 = lo(11 x r)
+ shd %r0,%r26,31,%r1 ; r1 = hi(10 x r)
+ addc %r1,%r0,%r1 ; r1 = hi(11 x r)
+; r in r1,,r29
+ zdep %r29,27,28,%r25 ; r25 = lo(10000 x r)
+ add %r25,%r29,%r25 ; r25 = lo(10001 x r)
+ shd %r1,%r29,28,%r29 ; r29 = hi(10000 x r)
+ addc %r29,%r1,%r29 ; r29 = hi(10001 x r)
+; r in r29,,r25
+ zdep %r25,23,24,%r1 ; r1 = lo(100000000 x r)
+ add %r1,%r25,%r1 ; r1 = lo(100000001 x r)
+ shd %r29,%r25,24,%r25 ; r25 = hi(100000000 x r)
+ addc %r25,%r29,%r25 ; r25 = hi(100000001 x r)
+; r in r25,,r1
+ zdep %r1,15,16,%r29
+ add %r29,%r1,%r29
+ shd %r25,%r1,16,%r1
+ addc %r1,%r25,%r1
+; r in r1,,r29
+ sh2add %r29,%r26,%r0 ; r0 = lo(1000 x r) + dividend
+ shd %r1,%r29,30,%r29 ; r29 = hi(1000 x r)
+ addc %r29,%r0,%r29
+ bv 0(ret)
+ extru %r29,28,29,result
+ .exit
+ .procend
+#endif
+
+
+#if defined (L_divU_12) && !defined (SMALL_LIB)
+#undef L_divU_12
+#define dividend %r26
+#define divisor %r25
+#define tmp %r1
+#define result %r29
+#define ret %r31
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_12
+$$divU_12
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ sh2add %r26,%r26,%r29 ; r29 = lo(101 x r)
+ shd %r0,%r26,30,%r1 ; r1 = hi(100 x r)
+ addc %r1,%r0,%r1 ; r1 = hi(101 x r)
+; r in r1,,r29
+ zdep %r29,27,28,%r25 ; r25 = lo(10000 x r)
+ add %r25,%r29,%r25 ; r25 = lo(10001 x r)
+ shd %r1,%r29,28,%r29 ; r29 = hi(10000 x r)
+ addc %r29,%r1,%r29 ; r29 = hi(10001 x r)
+; r in r29,,r25
+ zdep %r25,23,24,%r1 ; r1 = lo(100000000 x r)
+ add %r1,%r25,%r1 ; r1 = lo(100000001 x r)
+ shd %r29,%r25,24,%r25 ; r25 = hi(100000000 x r)
+ addc %r25,%r29,%r25 ; r25 = hi(100000001 x r)
+; r in r25,,r1
+ zdep %r1,15,16,%r29
+ add %r29,%r1,%r29
+ shd %r25,%r1,16,%r1
+ addc %r1,%r25,%r1
+; r in r1,,r29
+ sh1add %r29,%r26,%r0 ; r0 = lo(10 x r) + dividend
+ shd %r1,%r29,31,%r29 ; r29 = hi(10 x r)
+ addc %r29,%r0,%r29
+ bv 0(ret)
+ extru %r29,28,29,result
+ .exit
+ .procend
+#endif
+
+
+#ifdef L_divU_3
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_3
+$$divU_3
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divU
+ ldi 3,%r25
+ .exit
+ .procend
+ .import $$divU,MILLICODE
+#endif
+
+#ifdef L_divU_5
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_5
+$$divU_5
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divU
+ ldi 5,%r25
+ .exit
+ .procend
+ .import $$divU,MILLICODE
+#endif
+
+#ifdef L_divU_6
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_6
+$$divU_6
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divU
+ ldi 6,%r25
+ .exit
+ .procend
+ .import $$divU,MILLICODE
+#endif
+
+#ifdef L_divU_7
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_7
+$$divU_7
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divU
+ ldi 7,%r25
+ .exit
+ .procend
+ .import $$divU,MILLICODE
+#endif
+
+#ifdef L_divU_9
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_9
+$$divU_9
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divU
+ ldi 9,%r25
+ .exit
+ .procend
+ .import $$divU,MILLICODE
+#endif
+
+#ifdef L_divU_10
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_10
+$$divU_10
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divU
+ ldi 10,%r25
+ .exit
+ .procend
+ .import $$divU,MILLICODE
+#endif
+
+#ifdef L_divU_12
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_12
+$$divU_12
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divU
+ ldi 12,%r25
+ .exit
+ .procend
+ .import $$divU,MILLICODE
+#endif
+
+#ifdef L_divU_14
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_14
+$$divU_14
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divU
+ ldi 14,%r25
+ .exit
+ .procend
+ .import $$divU,MILLICODE
+#endif
+
+#ifdef L_divU_15
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divU_15
+$$divU_15
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divU
+ ldi 15,%r25
+ .exit
+ .procend
+ .import $$divU,MILLICODE
+#endif
+
+#ifdef L_divI_3
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divI_3
+$$divI_3
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divI
+ ldi 3,%r25
+ .exit
+ .procend
+ .import $$divI,MILLICODE
+#endif
+
+#ifdef L_divI_5
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divI_5
+$$divI_5
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divI
+ ldi 5,%r25
+ .exit
+ .procend
+ .import $$divI,MILLICODE
+#endif
+
+#ifdef L_divI_6
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divI_6
+$$divI_6
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divI
+ ldi 6,%r25
+ .exit
+ .procend
+ .import $$divI,MILLICODE
+#endif
+
+#ifdef L_divI_7
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divI_7
+$$divI_7
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divI
+ ldi 7,%r25
+ .exit
+ .procend
+ .import $$divI,MILLICODE
+#endif
+
+#ifdef L_divI_9
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divI_9
+$$divI_9
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divI
+ ldi 9,%r25
+ .exit
+ .procend
+ .import $$divI,MILLICODE
+#endif
+
+#ifdef L_divI_10
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divI_10
+$$divI_10
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divI
+ ldi 10,%r25
+ .exit
+ .procend
+ .import $$divI,MILLICODE
+#endif
+
+#ifdef L_divI_12
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divI_12
+$$divI_12
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divI
+ ldi 12,%r25
+ .exit
+ .procend
+ .import $$divI,MILLICODE
+#endif
+
+#ifdef L_divI_14
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divI_14
+$$divI_14
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divI
+ ldi 14,%r25
+ .exit
+ .procend
+ .import $$divI,MILLICODE
+#endif
+
+#ifdef L_divI_15
+ .space $TEXT$
+ .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
+ .align 4
+ .export $$divI_15
+$$divI_15
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ b $$divI
+ ldi 15,%r25
+ .exit
+ .procend
+ .import $$divI,MILLICODE
+#endif
diff --git a/gnu/usr.bin/gcc/config/pa/pa-gas.h b/gnu/usr.bin/gcc/config/pa/pa-gas.h
new file mode 100644
index 00000000000..d7da9e733b1
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/pa/pa-gas.h
@@ -0,0 +1,21 @@
+/* Definitions of target machine for GNU compiler, for HP-UX using GNU as.
+ Copyright (C) 1996 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT 0x88 /* TARGET_GAS + TARGET_JUMP_IN_DELAY */
diff --git a/gnu/usr.bin/gcc/config/pa/pa-hpux10.h b/gnu/usr.bin/gcc/config/pa/pa-hpux10.h
new file mode 100644
index 00000000000..ab7cee39389
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/pa/pa-hpux10.h
@@ -0,0 +1,71 @@
+/* Definitions of target machine for GNU compiler, for HP PA-RISC 1.1
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Tim Moore (moore@defmacro.cs.utah.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. */
+
+/* We can debug dynamically linked executables on hpux9; we also want
+ dereferencing of a NULL pointer to cause a SEGV. */
+#undef LINK_SPEC
+#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & 1)
+#define LINK_SPEC \
+ "%{!mpa-risc-1-0:%{!shared:-L/lib/pa1.1 -L/usr/lib/pa1.1 }} -z %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{shared:-b}"
+#else
+#define LINK_SPEC \
+ "-z %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{shared:-b}"
+#endif
+
+/* The hpux10 assembler requires a .LEVEL pseudo-op at the start of
+ the assembly file. */
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) \
+do { \
+ if (TARGET_SNAKE) \
+ fputs("\t.LEVEL 1.1\n", FILE); \
+ else \
+ fputs("\t.LEVEL 1.0\n", FILE); \
+ fputs ("\t.SPACE $PRIVATE$\n\
+\t.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31\n\
+\t.SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82\n\
+\t.SPACE $TEXT$\n\
+\t.SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44\n\
+\t.SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n\
+\t.IMPORT $global$,DATA\n\
+\t.IMPORT $$dyncall,MILLICODE\n", FILE);\
+ if (profile_flag)\
+ fprintf (FILE, "\t.IMPORT _mcount, CODE\n");\
+ if (write_symbols != NO_DEBUG) \
+ output_file_directive ((FILE), main_input_filename); \
+ } while (0)
+
+/* Under hpux10, the normal location of the `ld' and `as' programs is the
+ /usr/ccs/bin directory. */
+
+#ifndef CROSS_COMPILE
+#undef MD_EXEC_PREFIX
+#define MD_EXEC_PREFIX "/usr/ccs/bin/"
+#endif
+
+/* Under hpux10, the normal location of the various *crt*.o files is the
+ /usr/ccs/lib directory. */
+
+#ifndef CROSS_COMPILE
+#undef MD_STARTFILE_PREFIX
+#define MD_STARTFILE_PREFIX "/usr/ccs/lib/"
+#endif
+
diff --git a/gnu/usr.bin/gcc/config/pa/pa-pro-end.h b/gnu/usr.bin/gcc/config/pa/pa-pro-end.h
new file mode 100644
index 00000000000..8b1de1c5e5f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/pa/pa-pro-end.h
@@ -0,0 +1,41 @@
+/* Definitions of target machine for GNU compiler, for PRO.
+ Copyright (C) 1996, 1997 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Make GCC agree with types.h. */
+#undef SIZE_TYPE
+#undef PTRDIFF_TYPE
+
+#define SIZE_TYPE "unsigned int"
+#define PTRDIFF_TYPE "int"
+
+/* Like the default, except no -lg. */
+#undef LIB_SPEC
+#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p: -L/lib/libp/ -lc}%{pg: -L/lib/libp/ -lc}"
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Dhppa -DPWB -Acpu(hppa) -Amachine(hppa)"
+
+/* hpux8 and later have C++ compatible include files, so do not
+ pretend they are `extern "C"'. */
+#define NO_IMPLICIT_EXTERN_C
+
+/* We don't want a crt0.o to get linked in automatically, we want the
+ linker script to pull it in.
+ */
+#define STARTFILE_SPEC ""
diff --git a/gnu/usr.bin/gcc/config/pa/pa-pro.h b/gnu/usr.bin/gcc/config/pa/pa-pro.h
new file mode 100644
index 00000000000..f64ac2dc54c
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/pa/pa-pro.h
@@ -0,0 +1,78 @@
+/* Definitions of target machine for GNU compiler, for PRO.
+ Copyright (C) 1994, 1995, 1996 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Global constructor and destructor support. */
+/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
+
+ Note that we want to give these sections the SHF_WRITE attribute
+ because these sections will actually contain data (i.e. tables of
+ addresses of functions in the current root executable or shared library
+ file) and, in the case of a shared library, the relocatable addresses
+ will have to be properly resolved/relocated (and then written into) by
+ the dynamic linker when it actually attaches the given shared library
+ to the executing process. */
+
+#define CTORS_SECTION_ASM_OP "\t.section\t\".ctors\",#alloc,#write"
+#define DTORS_SECTION_ASM_OP "\t.section\t\".dtors\",#alloc,#write"
+
+#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; \
+ } \
+}
+
+
+/* A C statement (sans semicolon) to output an element in the table of
+ global destructors. */
+#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
+ do { \
+ dtors_section (); \
+ fputs ("\t.word\t ", FILE); \
+ assemble_name (FILE, NAME); \
+ fputs ("\n", FILE); \
+ } while (0)
+
+/* A C statement (sans semicolon) to output an element in the table of
+ global constructors. */
+#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
+ do { \
+ ctors_section (); \
+ fputs ("\t.word\t ", FILE); \
+ assemble_name (FILE, NAME); \
+ fputs ("\n", FILE); \
+ } while (0)
+
+/* JUMP_IN_DELAY + PORTABLE_RUNTIME + GAS + NO_SPACE_REGS + SOFT_FLOAT */
+#define TARGET_DEFAULT (4 + 8 + 64 + 128 + 256)
diff --git a/gnu/usr.bin/gcc/config/pa/rtems.h b/gnu/usr.bin/gcc/config/pa/rtems.h
new file mode 100644
index 00000000000..eebfd4f5cc1
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/pa/rtems.h
@@ -0,0 +1,26 @@
+/* Definitions of target machine for GNU compiler, for PRO.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Joel Sherrill (joel@OARcorp.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. */
+
+/* Specify predefined symbols in preprocessor. */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Dhppa -DPWB -Acpu(hppa) -Amachine(hppa) \
+ -Drtems -D__rtems__ -Asystem(rtems)"
diff --git a/gnu/usr.bin/gcc/config/pa/t-pro b/gnu/usr.bin/gcc/config/pa/t-pro
new file mode 100644
index 00000000000..f40b2e4e4d7
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/pa/t-pro
@@ -0,0 +1,38 @@
+LIBGCC1=libgcc1.null
+CROSS_LIBGCC1 = libgcc1.null
+LIB1ASMSRC =
+LIB1ASMFUNCS =
+
+LIBGCC1_TEST =
+
+ADA_CFLAGS=-mdisable-indexing
+
+LIB2FUNCS_EXTRA=fp-bit.c dp-bit.c lib2funcs.asm ee.asm ee_fp.asm
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+lib2funcs.asm: $(srcdir)/config/pa/lib2funcs.asm
+ rm -f lib2funcs.asm
+ cp $(srcdir)/config/pa/lib2funcs.asm .
+
+ee.asm: $(srcdir)/config/pa/ee.asm
+ rm -f ee.asm
+ cp $(srcdir)/config/pa/ee.asm .
+
+ee_fp.asm: $(srcdir)/config/pa/ee_fp.asm
+ rm -f ee_fp.asm
+ cp $(srcdir)/config/pa/ee_fp.asm .
+
+# Build the libraries for both speed and space optimizations
+
+MULTILIB_OPTIONS=mspace
+MULTILIB_DIRNAMES=space
+MULTILIB_MATCHES=
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
diff --git a/gnu/usr.bin/gcc/config/pa/xm-papro.h b/gnu/usr.bin/gcc/config/pa/xm-papro.h
new file mode 100644
index 00000000000..d36e2015ce7
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/pa/xm-papro.h
@@ -0,0 +1,58 @@
+/* Configuration for GNU C-compiler for PA-RISC.
+ Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+ Contributed by Michael Tiemann (tiemann@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. */
+
+extern int errno;
+
+/* #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
+
+/* Doubles are stored in memory with the high order word first. This
+ matters when cross-compiling. */
+#define HOST_WORDS_BIG_ENDIAN 1
+
+/* Place any machine-dependent include files here, in case we
+ are bootstrapping. */
+
+/* target machine dependencies.
+ tm.h is a symbolic link to the actual target specific file. */
+#include "tm.h"
+
+/* Arguments to use with `exit'. */
+#define SUCCESS_EXIT_CODE 0
+#define FATAL_EXIT_CODE 33
+
+/* Don't try to use sys_siglist. */
+#define NO_SYS_SIGLIST
+
+/* HP's compiler has problems with enum bitfields. */
+#define ONLY_INT_FIELDS
+
+/* Always claim to use C alloca; this prevents losing if building with
+ gcc -fno-builtin ... */
+#define USE_C_ALLOCA
diff --git a/gnu/usr.bin/gcc/config/psos.h b/gnu/usr.bin/gcc/config/psos.h
new file mode 100644
index 00000000000..d4043002a1c
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/psos.h
@@ -0,0 +1,183 @@
+/* Operating system specific defines to be used when targeting GCC for some
+ embedded system running pSOS. We assume GNU tools with ELF, but
+ try to maintain compatibility with the MRI tools. Based on svr4.h.
+ Copyright (C) 1996 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.
+
+ To use this file, make up a file with a name like:
+
+ ?????-psos.h
+
+ where ????? is replaced by the name of the basic hardware that you
+ are targeting for. Then, in the file ?????-psos.h, put something
+ like:
+
+ #include "?????.h"
+ #include "psos.h"
+
+ followed by any really system-specific defines (or overrides of
+ defines) which you find that you need.
+*/
+
+
+/* Define a symbol indicating that we are using psos.h. */
+
+#define USING_PSOS_H
+
+
+/* All pSOS targets currently use the ELF object file format. */
+
+#define OBJECT_FORMAT_ELF
+
+
+/* Provide a NULL STARTFILE_SPEC. The startfile cannot be specified
+ here because it depends on the architecture (e.g. 68K), the
+ board-support package (e.g. M162) and the run-time configuration
+ (e.g. application vs. ram-image vs. rom-image). Specify the
+ startfile in a linker-script created from the generic
+ architecture-specific linker-scripts. */
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC ""
+
+
+/* Predefined macros (independent of processor type). */
+
+#define CPP_PREDEFINES "-Dpsos"
+
+
+/* Implicit library calls should use ANSI memcpy rather than BSD
+ bcopy, etc. */
+
+#define TARGET_MEM_FUNCTIONS
+
+
+/* When using stabs, gcc2_compiled must be a stabs entry, not an
+ ordinary symbol, or gdb won't see it. The stabs entry must be
+ before the N_SO in order for gdb to find it. */
+
+#define ASM_IDENTIFY_GCC(FILE) \
+do \
+ { \
+ fputs (".stabs \"gcc2_compiled.\", 0x3c, 0, 0, 0\n", FILE); \
+ } \
+while (0)
+
+/* 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)
+
+/* Switch into a generic section. */
+
+#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
+ fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, \
+ (DECL) && TREE_CODE (DECL) == FUNCTION_DECL ? "ax" : \
+ (DECL) && DECL_READONLY_SECTION (DECL, RELOC) ? "a" : "aw")
+
+
+/* Define the pseudo-ops used to switch to the .ctors and .dtors
+ sections. */
+
+#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\""
+#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\""
+
+/* A default list of other sections which we might be "in" at any given
+ time. For targets that use additional sections (e.g. .tdesc) you
+ should override this definition in the target-specific file which
+ includes this file. */
+
+#undef EXTRA_SECTIONS
+#define EXTRA_SECTIONS in_ctors, in_dtors
+
+/* A default list of extra section function definitions. For targets
+ that use additional sections (e.g. .tdesc) you should override this
+ definition in the target-specific file which includes this file. */
+
+#undef EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS \
+ CTORS_SECTION_FUNCTION \
+ DTORS_SECTION_FUNCTION
+
+extern void text_section ();
+
+#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; \
+ } \
+}
+
+/* A C statement (sans semicolon) to output an element in the table of
+ global constructors. */
+
+#ifndef INT_ASM_OP
+#define INT_ASM_OP ".long"
+#endif
+#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)
+
+
+/* Use DBX debugging info by default. */
+
+#ifndef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+#endif
+
+/* For pSOS we use DBX debugging info. */
+
+#define DBX_DEBUGGING_INFO
+
+
+/* Prevent generation of an exit function. */
+
+#define HAVE_ATEXIT
+
diff --git a/gnu/usr.bin/gcc/config/ptx4.h b/gnu/usr.bin/gcc/config/ptx4.h
new file mode 100644
index 00000000000..db761655674
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/ptx4.h
@@ -0,0 +1,859 @@
+/* Operating system specific defines to be used when targeting GCC for some
+ generic System V Release 4 system.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Ron Guilmette (rfg@monkeys.com).
+ Renamed and changed to suit Dynix/ptx v4 and later.
+ Modified by Tim Wright (timw@sequent.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 a symbol indicating that we are using svr4.h. */
+#define USING_SVR4_H
+
+/* For the sake of libgcc2.c, indicate target supports atexit. */
+#define HAVE_ATEXIT
+
+/* Cpp, assembler, linker, library, and startfile spec's. */
+
+/* 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). Note however that there is no such
+ thing as a -T option for svr4. */
+
+#define SWITCH_TAKES_ARG(CHAR) \
+ ( (CHAR) == 'D' \
+ || (CHAR) == 'U' \
+ || (CHAR) == 'o' \
+ || (CHAR) == 'e' \
+ || (CHAR) == 'u' \
+ || (CHAR) == 'I' \
+ || (CHAR) == 'm' \
+ || (CHAR) == 'L' \
+ || (CHAR) == 'A' \
+ || (CHAR) == 'h' \
+ || (CHAR) == 'z')
+
+/* This defines which multi-letter switches take arguments. On svr4,
+ there are no such switches except those implemented by GCC itself. */
+
+#define WORD_SWITCH_TAKES_ARG(STR) \
+ (DEFAULT_WORD_SWITCH_TAKES_ARG (STR) \
+ && strcmp (STR, "Tdata") && strcmp (STR, "Ttext") \
+ && strcmp (STR, "Tbss"))
+
+/* You should redefine CPP_PREDEFINES in any file which includes this one.
+ The definition should be appropriate for the type of target system
+ involved, and it should include any -A (assertion) options which are
+ appropriate for the given target system. */
+#undef CPP_PREDEFINES
+
+/* Provide an ASM_SPEC appropriate for svr4. Here we try to support as
+ many of the specialized svr4 assembler options as seems reasonable,
+ given that there are certain options which we can't (or shouldn't)
+ support directly due to the fact that they conflict with other options
+ for other svr4 tools (e.g. ld) or with other options for GCC itself.
+ For example, we don't support the -o (output file) or -R (remove
+ input file) options because GCC already handles these things. We
+ also don't support the -m (run m4) option for the assembler because
+ that conflicts with the -m (produce load map) option of the svr4
+ linker. We do however allow passing arbitrary options to the svr4
+ assembler via the -Wa, option.
+
+ Note that gcc doesn't allow a space to follow -Y in a -Ym,* or -Yd,*
+ option.
+*/
+
+#undef ASM_SPEC
+#define ASM_SPEC \
+ "-no_0f_fix %{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
+
+/* svr4 assemblers need the `-' (indicating input from stdin) to come after
+ the -o option (and its argument) for some reason. If we try to put it
+ before the -o option, the assembler will try to read the file named as
+ the output file in the -o option as an input file (after it has already
+ written some stuff to it) and the binary stuff contained therein will
+ cause totally confuse the assembler, resulting in many spurious error
+ messages. */
+
+#undef ASM_FINAL_SPEC
+#define ASM_FINAL_SPEC "%{pipe:-}"
+
+/* Provide a LIB_SPEC appropriate for svr4. Here we tack on the default
+ standard C library (unless we are building a shared library). */
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{!shared:%{!symbolic:-lc}}"
+
+/* Provide a LIBGCC_SPEC appropriate for svr4. We also want to exclude
+ libgcc when -symbolic. */
+
+#undef LIBGCC_SPEC
+#define LIBGCC_SPEC "%{!shared:%{!symbolic:-lgcc}}"
+
+/* Provide an ENDFILE_SPEC appropriate for svr4. Here we tack on our own
+ magical crtend.o file (see crtstuff.c) which provides part of the
+ support for getting C++ file-scope static object constructed before
+ entering `main', followed by the normal svr3/svr4 "finalizer" file,
+ which is either `gcrtn.o' or `crtn.o'. */
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtend.o%s %{pg:gcrtn.o}%{!pg:crtn.o%s}"
+
+/* Provide a LINK_SPEC appropriate for svr4. Here we provide support
+ for the special GCC options -static, -shared, and -symbolic which
+ allow us to link things in one of these three modes by applying the
+ appropriate combinations of options at link-time. We also provide
+ support here for as many of the other svr4 linker options as seems
+ reasonable, given that some of them conflict with options for other
+ svr4 tools (e.g. the assembler). In particular, we do support the
+ -z*, -V, -b, -t, -Qy, -Qn, and -YP* options here, and the -e*,
+ -l*, -o*, -r, -s, -u*, and -L* options are directly supported
+ by gcc.c itself. We don't directly support the -m (generate load
+ map) option because that conflicts with the -m (run m4) option of
+ the svr4 assembler. We also don't directly support the svr4 linker's
+ -I* or -M* options because these conflict with existing GCC options.
+ We do however allow passing arbitrary options to the svr4 linker
+ via the -Wl, option. We don't support the svr4 linker's -a option
+ at all because it is totally useless and because it conflicts with
+ GCC's own -a option.
+
+ Note that gcc doesn't allow a space to follow -Y in a -YP,* option.
+
+ When the -G link option is used (-shared and -symbolic) a final link is
+ not being done. */
+
+#undef LINK_SPEC
+#define LINK_SPEC "%{h*} %{v:-V} \
+ %{b} %{Wl,*:%*} \
+ %{static:-dn -Bstatic} \
+ %{shared:-G -dy -z text} \
+ %{symbolic:-Bsymbolic -G -dy -z text} \
+ %{G:-G} \
+ %{YP,*} \
+ %{!YP,*:%{p:-Y P,/lib/libp:/usr/lib/libp:/lib:/usr/lib} \
+ %{!p:-Y P,/lib:/usr/lib}} \
+ %{Qy:} %{!Qn:-Qy}"
+
+/* Gcc automatically adds in one of the files /lib/values-Xc.o,
+ /lib/values-Xa.o, or /lib/values-Xt.o for each final link
+ step (depending upon the other gcc options selected, such as
+ -traditional and -ansi). These files each contain one (initialized)
+ copy of a special variable called `_lib_version'. Each one of these
+ files has `_lib_version' initialized to a different (enum) value.
+ The SVR4 library routines query the value of `_lib_version' at run
+ to decide how they should behave. Specifically, they decide (based
+ upon the value of `_lib_version') if they will act in a strictly ANSI
+ conforming manner or not.
+*/
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "%{!shared: \
+ %{!symbolic: \
+ %{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}}}\
+ %{pg:gcrti.o%s}%{!pg:crti.o%s} \
+ %{ansi:values-Xc.o%s} \
+ %{!ansi: \
+ %{traditional:values-Xt.o%s} \
+ %{!traditional:values-Xa.o%s}} \
+ crtbegin.o%s"
+
+/* 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"
+
+#define ASM_FILE_END(FILE) \
+do { \
+ fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \
+ IDENT_ASM_OP, version_string); \
+ } while (0)
+
+/* Allow #sccs in preprocessor. */
+
+#define SCCS_DIRECTIVE
+
+/* Output #ident as a .ident. */
+
+#define ASM_OUTPUT_IDENT(FILE, NAME) \
+ fprintf (FILE, "\t%s\t\"%s\"\n", IDENT_ASM_OP, NAME);
+
+/* Use periods rather than dollar signs in special g++ assembler names. */
+
+#define NO_DOLLAR_IN_LABEL
+
+/* Writing `int' for a bitfield forces int alignment for the structure. */
+
+#define PCC_BITFIELD_TYPE_MATTERS 1
+
+/* Implicit library calls should use memcpy, not bcopy, etc. */
+
+#define TARGET_MEM_FUNCTIONS
+
+/* Handle #pragma weak and #pragma pack. */
+
+#define HANDLE_SYSV_PRAGMA
+
+/* System V Release 4 uses DWARF debugging info. */
+
+#define DWARF_DEBUGGING_INFO
+
+/* The numbers used to denote specific machine registers in the System V
+ Release 4 DWARF debugging information are quite likely to be totally
+ different from the numbers used in BSD stabs debugging information
+ for the same kind of target machine. Thus, we undefine the macro
+ DBX_REGISTER_NUMBER here as an extra inducement to get people to
+ provide proper machine-specific definitions of DBX_REGISTER_NUMBER
+ (which is also used to provide DWARF registers numbers in dwarfout.c)
+ in their tm.h files which include this file. */
+
+#undef DBX_REGISTER_NUMBER
+
+/* gas on SVR4 supports the use of .stabs. Permit -gstabs to be used
+ in general, although it will only work when using gas. */
+
+#define DBX_DEBUGGING_INFO
+
+/* Use DWARF debugging info by default. */
+
+#ifndef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
+#endif
+
+/* Make LBRAC and RBRAC addresses relative to the start of the
+ function. The native Solaris stabs debugging format works this
+ way, gdb expects it, and it reduces the number of relocation
+ entries. */
+
+#define DBX_BLOCKS_FUNCTION_RELATIVE 1
+
+/* When using stabs, gcc2_compiled must be a stabs entry, not an
+ ordinary symbol, or gdb won't see it. The stabs entry must be
+ before the N_SO in order for gdb to find it. */
+
+#define ASM_IDENTIFY_GCC(FILE) \
+do \
+ { \
+ if (write_symbols != DBX_DEBUG) \
+ fputs ("gcc2_compiled.:\n", FILE); \
+ else \
+ fputs ("\t.stabs\t\"gcc2_compiled.\", 0x3c, 0, 0, 0\n", FILE); \
+ } \
+while (0)
+
+/* Like block addresses, stabs line numbers are relative to the
+ current function. */
+
+#define ASM_OUTPUT_SOURCE_LINE(file, line) \
+do \
+ { \
+ static int sym_lineno = 1; \
+ fprintf (file, ".stabn 68,0,%d,.LM%d-", \
+ line, sym_lineno); \
+ assemble_name (file, \
+ XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
+ fprintf (file, "\n.LM%d:\n", sym_lineno); \
+ sym_lineno += 1; \
+ } \
+while (0)
+
+/* In order for relative line numbers to work, we must output the
+ stabs entry for the function name first. */
+
+#define DBX_FUNCTION_FIRST
+
+/* Generate a blank trailing N_SO to mark the end of the .o file, since
+ we can't depend upon the linker to mark .o file boundaries with
+ embedded stabs. */
+
+#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
+ fprintf (FILE, \
+ "\t.text\n\t.stabs \"\",%d,0,0,.Letext\n.Letext:\n", N_SO)
+
+/* Define the actual types of some ANSI-mandated types. (These
+ definitions should work for most SVR4 systems). */
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "int"
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "long int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+/* This causes trouble, because it requires the host machine
+ to support ANSI C. */
+/* #define MULTIBYTE_CHARS */
+
+#undef ASM_BYTE_OP
+#define ASM_BYTE_OP ".byte"
+
+#undef SET_ASM_OP
+#define SET_ASM_OP ".set"
+
+/* This is how to begin an assembly language file. Most svr4 assemblers want
+ at least a .file directive to come first, and some want to see a .version
+ directive come right after that. Here we just establish a default
+ which generates only the .file directive. If you need a .version
+ directive for any specific target, you should override this definition
+ in the target-specific file which includes this one. */
+
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) \
+ output_file_directive ((FILE), main_input_filename)
+
+/* This is how to allocate empty space in some section. The .zero
+ pseudo-op is used for this on most svr4 assemblers. */
+
+#define SKIP_ASM_OP ".zero"
+
+#undef ASM_OUTPUT_SKIP
+#define ASM_OUTPUT_SKIP(FILE,SIZE) \
+ fprintf (FILE, "\t%s\t%u\n", SKIP_ASM_OP, (SIZE))
+
+/* The prefix to add to user-visible assembler symbols.
+
+ For System V Release 4 the convention is *not* to prepend a leading
+ underscore onto user-level symbol names. */
+
+#undef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX ""
+
+/* This is how to output an internal numbered label where
+ PREFIX is the class of label and NUM is the number within the class.
+
+ For most svr4 systems, the convention is that any symbol which begins
+ with a period is not put into the linker symbol table by the assembler. */
+
+#undef ASM_OUTPUT_INTERNAL_LABEL
+#define ASM_OUTPUT_INTERNAL_LABEL(FILE, PREFIX, NUM) \
+do { \
+ fprintf (FILE, ".%s%d:\n", PREFIX, NUM); \
+} while (0)
+
+/* This is how to store into the string LABEL
+ 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'.
+
+ For most svr4 systems, the convention is that any symbol which begins
+ with a period is not put into the linker symbol table by the assembler. */
+
+#undef ASM_GENERATE_INTERNAL_LABEL
+#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
+do { \
+ sprintf (LABEL, "*.%s%d", PREFIX, NUM); \
+} while (0)
+
+/* Output the label which precedes a jumptable. Note that for all svr4
+ systems where we actually generate jumptables (which is to say every
+ svr4 target except i386, where we use casesi instead) we put the jump-
+ tables into the .rodata section and since other stuff could have been
+ put into the .rodata section prior to any given jumptable, we have to
+ make sure that the location counter for the .rodata section gets pro-
+ perly re-aligned prior to the actual beginning of the jump table. */
+
+#define ALIGN_ASM_OP ".align"
+
+#ifndef ASM_OUTPUT_BEFORE_CASE_LABEL
+#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
+ ASM_OUTPUT_ALIGN ((FILE), 2);
+#endif
+
+#undef ASM_OUTPUT_CASE_LABEL
+#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,JUMPTABLE) \
+ do { \
+ ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE) \
+ ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); \
+ } while (0)
+
+/* The standard SVR4 assembler seems to require that certain builtin
+ library routines (e.g. .udiv) be explicitly declared as .globl
+ in each assembly file where they are referenced. */
+
+#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
+ ASM_GLOBALIZE_LABEL (FILE, XSTR (FUN, 0))
+
+/* This says how to output assembler code to declare an
+ uninitialized external linkage data object. Under SVR4,
+ the linker seems to want the alignment of data objects
+ to depend on their types. We do exactly that here. */
+
+#define COMMON_ASM_OP ".comm"
+
+#undef ASM_OUTPUT_ALIGNED_COMMON
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
+do { \
+ fprintf ((FILE), "\t%s\t", COMMON_ASM_OP); \
+ assemble_name ((FILE), (NAME)); \
+ fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
+} while (0)
+
+/* This says how to output assembler code to declare an
+ uninitialized internal linkage data object. Under SVR4,
+ the linker seems to want the alignment of data objects
+ to depend on their types. We do exactly that here. */
+
+#define LOCAL_ASM_OP ".local"
+
+#undef ASM_OUTPUT_ALIGNED_LOCAL
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
+do { \
+ fprintf ((FILE), "\t%s\t", LOCAL_ASM_OP); \
+ assemble_name ((FILE), (NAME)); \
+ fprintf ((FILE), "\n"); \
+ ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \
+} while (0)
+
+/* This is the pseudo-op used to generate a 32-bit word of data with a
+ specific value in some section. This is the same for all known svr4
+ assemblers. */
+
+#define INT_ASM_OP ".long"
+
+/* This is the pseudo-op used to generate a contiguous sequence of byte
+ values from a double-quoted string WITHOUT HAVING A TERMINATING NUL
+ AUTOMATICALLY APPENDED. This is the same for most svr4 assemblers. */
+
+#undef ASCII_DATA_ASM_OP
+#define ASCII_DATA_ASM_OP ".ascii"
+
+/* 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. */
+
+#define USE_CONST_SECTION 1
+
+#define CONST_SECTION_ASM_OP ".section\t.rodata"
+
+/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
+
+ Note that we want to give these sections the SHF_WRITE attribute
+ because these sections will actually contain data (i.e. tables of
+ addresses of functions in the current root executable or shared library
+ file) and, in the case of a shared library, the relocatable addresses
+ will have to be properly resolved/relocated (and then written into) by
+ the dynamic linker when it actually attaches the given shared library
+ to the executing process. (Note that on SVR4, you may wish to use the
+ `-z text' option to the ELF linker, when building a shared library, as
+ an additional check that you are doing everything right. But if you do
+ use the `-z text' option when building a shared library, you will get
+ errors unless the .ctors and .dtors sections are marked as writable
+ via the SHF_WRITE attribute.) */
+
+#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\""
+#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\""
+
+/* On svr4, we *do* have support for the .init and .fini sections, and we
+ can put stuff in there to be executed before and after `main'. We let
+ crtstuff.c and other files know this by defining the following symbols.
+ The definitions say how to change sections to the .init and .fini
+ sections. This is the same for all known svr4 assemblers. */
+
+#define INIT_SECTION_ASM_OP ".section\t.init"
+#define FINI_SECTION_ASM_OP ".section\t.fini"
+
+/* A default list of other sections which we might be "in" at any given
+ time. For targets that use additional sections (e.g. .tdesc) you
+ should override this definition in the target-specific file which
+ includes this file. */
+
+#undef EXTRA_SECTIONS
+#define EXTRA_SECTIONS in_const, in_ctors, in_dtors
+
+/* A default list of extra section function definitions. For targets
+ that use additional sections (e.g. .tdesc) you should override this
+ definition in the target-specific file which includes this file. */
+
+#undef EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS \
+ CONST_SECTION_FUNCTION \
+ CTORS_SECTION_FUNCTION \
+ DTORS_SECTION_FUNCTION
+
+#define READONLY_DATA_SECTION() const_section ()
+
+extern void text_section ();
+
+#define CONST_SECTION_FUNCTION \
+void \
+const_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; \
+ } \
+}
+
+#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; \
+ } \
+}
+
+/* Switch into a generic section.
+ This is currently only used to support section attributes.
+
+ We make the section read-only and executable for a function decl,
+ read-only for a const data decl, and writable for a non-const data decl. */
+#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
+ fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, \
+ (DECL) && TREE_CODE (DECL) == FUNCTION_DECL ? "ax" : \
+ (DECL) && DECL_READONLY_SECTION (DECL, RELOC) ? "a" : "aw")
+
+
+/* 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)
+
+/* 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 ((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. */
+
+#undef SELECT_RTX_SECTION
+#define SELECT_RTX_SECTION(MODE,RTX) const_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"
+
+/* 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"
+
+/* 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) \
+ { \
+ 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))); \
+ } \
+ } 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)
+
+/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
+ ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
+ corresponds to a particular byte value [0..255]. For any
+ given byte value, if the value in the corresponding table
+ position is zero, the given character can be output directly.
+ If the table value is 1, the byte must be output as a \ooo
+ octal escape. If the tables value is anything else, then the
+ byte value should be output as a \ followed by the value
+ in the table. Note that we can use standard UN*X escape
+ sequences for many control characters, but we don't use
+ \a to represent BEL because some svr4 assemblers (e.g. on
+ the i386) don't know about that. Also, we don't use \v
+ since some versions of gas, such as 2.2 did not accept it. */
+
+#define ESCAPES \
+"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
+\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\
+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"
+
+/* Some svr4 assemblers have a limit on the number of characters which
+ can appear in the operand of a .string directive. If your assembler
+ has such a limitation, you should define STRING_LIMIT to reflect that
+ limit. Note that at least some svr4 assemblers have a limit on the
+ actual number of bytes in the double-quoted string, and that they
+ count each character in an escape sequence as one byte. Thus, an
+ escape sequence like \377 would count as four bytes.
+
+ If your target assembler doesn't support the .string directive, you
+ should define this to zero.
+*/
+
+#define STRING_LIMIT ((unsigned) 256)
+
+#define STRING_ASM_OP ".string"
+
+/* The routine used to output NUL terminated strings. 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, especially for targets like the i386
+ (where the only alternative is to output character sequences as
+ comma separated lists of numbers). */
+
+#define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \
+ do \
+ { \
+ register unsigned char *_limited_str = (unsigned char *) (STR); \
+ register unsigned ch; \
+ fprintf ((FILE), "\t%s\t\"", STRING_ASM_OP); \
+ for (; ch = *_limited_str; _limited_str++) \
+ { \
+ register int escape; \
+ switch (escape = ESCAPES[ch]) \
+ { \
+ case 0: \
+ putc (ch, (FILE)); \
+ break; \
+ case 1: \
+ fprintf ((FILE), "\\%03o", ch); \
+ break; \
+ default: \
+ putc ('\\', (FILE)); \
+ putc (escape, (FILE)); \
+ break; \
+ } \
+ } \
+ fprintf ((FILE), "\"\n"); \
+ } \
+ while (0)
+
+/* 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 >= 60) \
+ { \
+ fprintf ((FILE), "\"\n"); \
+ 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) \
+ { \
+ fprintf ((FILE), "\"\n"); \
+ bytes_in_chunk = 0; \
+ } \
+ ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes); \
+ _ascii_bytes = p; \
+ } \
+ else \
+ { \
+ register int escape; \
+ register unsigned ch; \
+ if (bytes_in_chunk == 0) \
+ fprintf ((FILE), "\t%s\t\"", ASCII_DATA_ASM_OP); \
+ switch (escape = ESCAPES[ch = *_ascii_bytes]) \
+ { \
+ case 0: \
+ putc (ch, (FILE)); \
+ bytes_in_chunk++; \
+ break; \
+ case 1: \
+ fprintf ((FILE), "\\%03o", ch); \
+ bytes_in_chunk += 4; \
+ break; \
+ default: \
+ putc ('\\', (FILE)); \
+ putc (escape, (FILE)); \
+ bytes_in_chunk += 2; \
+ break; \
+ } \
+ } \
+ } \
+ if (bytes_in_chunk > 0) \
+ fprintf ((FILE), "\"\n"); \
+ } \
+ while (0)
+
+/* All SVR4 targets use the ELF object file format. */
+#define OBJECT_FORMAT_ELF
diff --git a/gnu/usr.bin/gcc/config/rs6000/cygwin32.h b/gnu/usr.bin/gcc/config/rs6000/cygwin32.h
new file mode 100644
index 00000000000..f527736a020
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/cygwin32.h
@@ -0,0 +1,67 @@
+/* Operating system specific defines to be used when targeting GCC for
+ hosting on Windows NT 3.x, using the Cygnus API
+
+ This is different to the winnt.h file, since that is used
+ to build GCC for use with a windows style library and tool
+ set, winnt.h uses the Microsoft tools to do that.
+
+ Copyright (C) 1996, 1997 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. */
+
+
+/* Ugly hack */
+#include "rs6000/win-nt.h"
+
+
+#ifdef CPP_PREDEFINES
+#undef CPP_PREDEFINES
+#endif
+
+#define CPP_PREDEFINES "-D_WIN32 -DWINNT -D__CYGWIN32__ -DPOSIX \
+ -D_POWER -D_ARCH_PPC -D__PPC__ -Asystem(winnt) -Acpu(powerpc) -Amachine(powerpc)"
+
+#undef CPP_SPEC
+#define CPP_SPEC "-remap %{posix: -D_POSIX_SOURCE} %(cpp_cpu)"
+
+/* We have to dynamic link to get to the system DLLs. All of libc, libm and
+ the Unix stuff is in cygwin.dll. The import library is called
+ 'libcygwin.a'. For Windows applications, include more libraries, but
+ always include kernel32. We'd like to specific subsystem windows to
+ ld, but that doesn't work just yet. */
+
+#undef LIB_SPEC
+#define LIB_SPEC "-lcygwin %{mwindows:-luser32 -lgdi32 -lcomdlg32} -lkernel32"
+
+#undef LINK_SPEC
+#define LINK_SPEC "%{v:-V}"
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "crti%O%s crt0%O%s"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtn%O%s"
+
+#define PTRDIFF_TYPE "int"
+#define WCHAR_UNSIGNED 1
+#define WCHAR_TYPE_SIZE 16
+#define WCHAR_TYPE "short unsigned int"
+
+#define DBX_DEBUGGING_INFO
+#undef SDB_DEBUGGING_INFO
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
diff --git a/gnu/usr.bin/gcc/config/rs6000/eabi-ci.asm b/gnu/usr.bin/gcc/config/rs6000/eabi-ci.asm
new file mode 100644
index 00000000000..6b753ca1239
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/eabi-ci.asm
@@ -0,0 +1,119 @@
+# crti.s for eabi
+
+# Copyright (C) 1996 Free Software Foundation, Inc.
+# Written By Michael Meissner
+#
+# 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 .got* and other
+# special sections. It is linked in first before other modules.
+
+ .file "crti.s"
+ .ident "GNU C crti.s"
+
+#include <ppc-asm.h>
+
+ .section ".got","aw"
+ .globl __GOT_START__
+ .type __GOT_START__,@object
+__GOT_START__:
+
+ .section ".got1","aw"
+ .globl __GOT1_START__
+ .type __GOT1_START__,@object
+__GOT1_START__:
+
+ .section ".got2","aw"
+ .globl __GOT2_START__
+ .type __GOT2_START__,@object
+__GOT2_START__:
+
+ .section ".fixup","aw"
+ .globl __FIXUP_START__
+ .type __FIXUP_START__,@object
+__FIXUP_START__:
+
+ .section ".ctors","aw"
+ .globl __CTOR_LIST__
+ .type __CTOR_LIST__,@object
+__CTOR_LIST__:
+
+ .section ".dtors","aw"
+ .globl __DTOR_LIST__
+ .type __DTOR_LIST__,@object
+__DTOR_LIST__:
+
+ .section ".sdata","aw"
+ .globl __SDATA_START__
+ .type __SDATA_START__,@object
+ .weak _SDA_BASE_
+ .type _SDA_BASE_,@object
+__SDATA_START__:
+_SDA_BASE_:
+
+ .section ".sbss","aw",@nobits
+ .globl __SBSS_START__
+ .type __SBSS_START__,@object
+__SBSS_START__:
+
+ .section ".sdata2","a"
+ .weak _SDA2_BASE_
+ .type _SDA2_BASE_,@object
+ .globl __SDATA2_START__
+ .type __SDATA2_START__,@object
+__SDATA2_START__:
+_SDA2_BASE_:
+
+ .section ".sbss2","a"
+ .globl __SBSS2_START__
+ .type __SBSS2_START__,@object
+__SBSS2_START__:
+
+ .section ".gcc_except_table","aw"
+ .globl __EXCEPT_START__
+ .type __EXCEPT_START__,@object
+__EXCEPT_START__:
+
+# Head of __init function used for static constructors in Solaris
+ .section ".init","ax"
+ .align 2
+FUNC_START(__init)
+ stwu 1,-8(1)
+ mflr 0
+ stw 0,12(1)
+
+# Head of __fini function used for static destructors in Solaris
+ .section ".fini","ax"
+ .align 2
+FUNC_START(__fini)
+ stwu 1,-8(1)
+ mflr 0
+ stw 0,12(1)
diff --git a/gnu/usr.bin/gcc/config/rs6000/eabi-cn.asm b/gnu/usr.bin/gcc/config/rs6000/eabi-cn.asm
new file mode 100644
index 00000000000..06e895638dc
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/eabi-cn.asm
@@ -0,0 +1,109 @@
+# crtn.s for eabi
+
+# Copyright (C) 1996 Free Software Foundation, Inc.
+# Written By Michael Meissner
+#
+# 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 ending points for the .got* and other
+# special sections. It is linked in last after other modules.
+
+ .file "crtn.s"
+ .ident "GNU C crtn.s"
+
+ .section ".got","aw"
+ .globl __GOT_END__
+ .type __GOT_END__,@object
+__GOT_END__:
+
+ .section ".got1","aw"
+ .globl __GOT1_END__
+ .type __GOT1_END__,@object
+__GOT1_END__:
+
+ .section ".got2","aw"
+ .globl __GOT2_END__
+ .type __GOT2_END__,@object
+__GOT2_END__:
+
+ .section ".fixup","aw"
+ .globl __FIXUP_END__
+ .type __FIXUP_END__,@object
+__FIXUP_END__:
+
+ .section ".ctors","aw"
+ .globl __CTOR_END__
+ .type __CTOR_END__,@object
+__CTOR_END__:
+
+ .section ".dtors","aw"
+ .globl __DTOR_END__
+ .type __DTOR_END__,@object
+__DTOR_END__:
+
+ .section ".sdata","aw"
+ .globl __SDATA_END__
+ .type __SDATA_END__,@object
+__SDATA_END__:
+
+ .section ".sbss","aw",@nobits
+ .globl __SBSS_END__
+ .type __SBSS_END__,@object
+__SBSS_END__:
+
+ .section ".sdata2","a"
+ .globl __SDATA2_END__
+ .type __SDATA2_END__,@object
+__SDATA2_END__:
+
+ .section ".sbss2","a"
+ .globl __SBSS2_END__
+ .type __SBSS2_END__,@object
+__SBSS2_END__:
+
+ .section ".gcc_except_table","aw"
+ .globl __EXCEPT_END__
+ .type __EXCEPT_END__,@object
+__EXCEPT_END__:
+
+# Tail of __init used for static constructors in Solaris
+ .section ".init","ax"
+ lwz 0,12(1)
+ mtlr 0
+ addi 1,1,8
+ blr
+
+# Tail of __fini used for static destructors in Solaris
+ .section ".fini","ax"
+ lwz 0,12(1)
+ mtlr 0
+ addi 1,1,8
+ blr
diff --git a/gnu/usr.bin/gcc/config/rs6000/linux.h b/gnu/usr.bin/gcc/config/rs6000/linux.h
new file mode 100644
index 00000000000..10474e4d5cf
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/linux.h
@@ -0,0 +1,67 @@
+/* Definitions of target machine for GNU compiler,
+ for IBM RS/6000 running AIX version 3.1.
+ Copyright (C) 1996, 1997 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "rs6000/sysv4.h"
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES \
+ "-DPPC -Dunix -Dlinux -Dpowerpc -Asystem(unix) -Asystem(linux) -Acpu(powerpc) -Amachine(powerpc)"
+
+#undef LINK_SPEC
+#define LINK_SPEC "-m elf32ppc %{shared:-shared} \
+ %{!shared: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \
+ %{static:-static}}"
+
+#undef LIB_DEFAULT_SPEC
+#define LIB_DEFAULT_SPEC "%(lib_linux)"
+
+#undef STARTFILE_DEFAULT_SPEC
+#define STARTFILE_DEFAULT_SPEC "%(startfile_linux)"
+
+#undef ENDFILE_DEFAULT_SPEC
+#define ENDFILE_DEFAULT_SPEC "%(endfile_linux)"
+
+#undef LINK_START_DEFAULT_SPEC
+#define LINK_START_DEFAULT_SPEC "%(link_start_linux)"
+
+#undef LINK_OS_DEFAULT_SPEC
+#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (PowerPC GNU/Linux)");
+
+/* Define this macro as a C expression for the initializer of an
+ array of string to tell the driver program which options are
+ defaults for this target and thus do not need to be handled
+ specially when using `MULTILIB_OPTIONS'.
+
+ Do not define this macro if `MULTILIB_OPTIONS' is not defined in
+ the target makefile fragment or if none of the options listed in
+ `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
+
+#undef MULTILIB_DEFAULTS
+#define MULTILIB_DEFAULTS { "mbig", "mcall-linux" }
+
+#undef DEFAULT_VTABLE_THUNKS
+#define DEFAULT_VTABLE_THUNKS 1
diff --git a/gnu/usr.bin/gcc/config/rs6000/nt-ci.asm b/gnu/usr.bin/gcc/config/rs6000/nt-ci.asm
new file mode 100644
index 00000000000..67ca9564abf
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/nt-ci.asm
@@ -0,0 +1,48 @@
+# crti.s for Windows NT
+
+# Copyright (C) 1996 Free Software Foundation, Inc.
+# Written By Michael Meissner
+#
+# 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 static constructors
+# and destructors. It is linked in first before other modules.
+
+ .file "crti.s"
+ .ident "GNU C crti.s"
+
+ .section .ctors,"w"
+ .globl __CTOR_LIST__
+__CTOR_LIST__:
+
+ .section .dtors,"w"
+ .globl __DTOR_LIST__
+__DTOR_LIST__:
diff --git a/gnu/usr.bin/gcc/config/rs6000/nt-cn.asm b/gnu/usr.bin/gcc/config/rs6000/nt-cn.asm
new file mode 100644
index 00000000000..dd6daf29b2e
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/nt-cn.asm
@@ -0,0 +1,48 @@
+# crtn.s for Windows NT
+
+# Copyright (C) 1996 Free Software Foundation, Inc.
+# Written By Michael Meissner
+#
+# 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 ending points for the static constructors
+# and destructors. It is linked in last after other modules.
+
+ .file "crtn.s"
+ .ident "GNU C crtn.s"
+
+ .section .ctors,"w"
+ .globl __CTOR_END__
+__CTOR_END__:
+
+ .section .dtors,"w"
+ .globl __DTOR_END__
+__DTOR_END__:
diff --git a/gnu/usr.bin/gcc/config/rs6000/ntstack.asm b/gnu/usr.bin/gcc/config/rs6000/ntstack.asm
new file mode 100644
index 00000000000..aa4179e7a79
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/ntstack.asm
@@ -0,0 +1,42 @@
+# Allocate stack for NT, inserting stack probes every 4k pages
+
+ .file "ntstack.asm"
+
+# Setup MS Structured-Exception-Handling
+ .pdata
+ .align 2
+ .ualong ..__allocate_stack,__allocate_stack.e,0,0,__allocate_stack.b
+
+# Switch to the relocation section
+ .reldata
+ .globl __allocate_stack
+ .globl ..__allocate_stack
+__allocate_stack:
+ .ualong ..__allocate_stack,.toc
+
+ .text
+ .align 2
+..__allocate_stack:
+ .function ..__allocate_stack
+__allocate_stack.b:
+ addi 3,3,15 # round up to 16 byte alignment
+ lwz 0,0(1) # old stack link
+ rlwinm 3,3,0,0,28
+ srawi. 4,3,12 # get # of pages to check
+ neg 3,3 # negate so we can use stwux
+ bgt- 0,.Lcheck
+ stwux 0,1,3 # small request, just decrement and return
+ blr
+
+.Lcheck:
+ mtctr 4 # number of pages to check
+ mr 5,1 # tmp pointer
+.Lloop:
+ lwzu 6,-4096(5) # touch the page
+ bdnz+ .Lloop # and loop back
+
+ stwux 0,1,3 # update stack pointer
+ blr
+
+__allocate_stack.e:
+FE_MOT_RESVD..__allocate_stack:
diff --git a/gnu/usr.bin/gcc/config/rs6000/rtems.h b/gnu/usr.bin/gcc/config/rs6000/rtems.h
new file mode 100644
index 00000000000..10c6bf77b57
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/rtems.h
@@ -0,0 +1,32 @@
+/* Definitions for rtems targeting a PowerPC using elf.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Joel Sherrill (joel@OARcorp.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 "rs6000/eabi.h"
+
+/* Specify predefined symbols in preprocessor. */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-DPPC -Drtems -D__rtems__ \
+ -Asystem(rtems) -Acpu(powerpc) -Amachine(powerpc)"
+
+/* rtems is in the SUBTARGET_SWITCHES in rs6000/sysv4.h */
+
+/* end of powerpc-rtems.h */
diff --git a/gnu/usr.bin/gcc/config/rs6000/sol-c0.c b/gnu/usr.bin/gcc/config/rs6000/sol-c0.c
new file mode 100644
index 00000000000..bf935c3d371
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/sol-c0.c
@@ -0,0 +1,122 @@
+/* Solaris PowerPC startfile. */
+/* Copyright (C) 1996 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. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself 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. */
+
+extern char **_environ;
+
+extern int atexit (void (*__func) (void));
+extern void __init (void) __attribute__ ((__longcall__));
+extern void __fini (void) __attribute__ ((__longcall__));
+
+typedef void (*func_ptr) (void);
+int (*__atexit)(func_ptr) = atexit;
+
+/* Exception handling */
+struct ex_shared1 {
+ void *prev;
+ void *next;
+ char *text_start;
+ char *range_start;
+ char *text_end;
+ char *range_end;
+};
+
+struct ex_shared {
+ void (*ex_register) (struct ex_shared1 *);
+ void (*ex_deregister) (struct ex_shared1 *);
+ struct ex_shared1 shared_info;
+};
+
+extern char _ex_text0[], _ex_text1[];
+extern char _ex_range0[], _ex_range1[];
+extern void _ex_register (struct ex_shared1 *);
+extern void _ex_deregister (struct ex_shared1 *);
+extern char _SDA_BASE_[];
+extern char _SDA2_BASE_[];
+
+struct ex_shared shared __attribute__((section(".ex_shared"))) = {
+ _ex_register,
+ _ex_deregister,
+ {
+ (void *)0,
+ (void *)0,
+ _ex_text0,
+ _ex_range0,
+ _ex_text1,
+ _ex_range1
+ }
+};
+
+static void
+deregister (void)
+{
+ (* shared.ex_deregister) (&shared.shared_info);
+}
+
+/* Start function. */
+void
+_start(int argc, char *argv[], char *envp[], void *auxp, void (*termfunc)())
+{
+ int ret;
+ int dummy = 0;
+
+#if 0
+ /* Disable this for now, it causes an impossible reload. */
+ /* Load up r13/r2 before we do anything else. */
+ __asm__ volatile ("mr %%r13,%0;mr %%r2,%1" : "=r" (dummy) : "r" (&_SDA_BASE_[0]), "r" (&_SDA2_BASE_[0]), "r" (dummy));
+#endif
+
+ _environ = envp + dummy;
+
+ /* Register loader termination function (the || dummy is to make sure the above asm
+ is not optimized away). */
+ if (termfunc)
+ atexit (termfunc);
+
+ /* Register exception handler if needed */
+ if (shared.ex_register)
+ (* shared.ex_register) (&shared.shared_info);
+
+ if (shared.ex_deregister)
+ atexit (deregister);
+
+ /* Call any global constructors and destructors. */
+ __init ();
+
+ atexit (__fini);
+
+ /* Call the main program now */
+ ret = main (argc, argv, envp, auxp);
+
+ /* Return to the os */
+ exit (ret);
+}
+
+/* Provide a dummy __eabi in case main got compiled without -mcall-solaris. */
+void
+__eabi ()
+{
+}
diff --git a/gnu/usr.bin/gcc/config/rs6000/sol-ci.asm b/gnu/usr.bin/gcc/config/rs6000/sol-ci.asm
new file mode 100644
index 00000000000..d0eced3a09c
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/sol-ci.asm
@@ -0,0 +1,104 @@
+# crti.s for solaris
+
+# Copyright (C) 1996 Free Software Foundation, Inc.
+# Written By Michael Meissner
+#
+# 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 .got* and other
+# special sections. It is linked in first before other modules.
+
+ .file "scrti.s"
+ .ident "GNU C scrti.s"
+
+# Start of .text
+ .section ".text"
+ .globl _ex_text0
+_ex_text0:
+
+# Exception range
+ .section ".exception_ranges","aw"
+ .globl _ex_range0
+_ex_range0:
+
+# List of C++ constructors
+ .section ".ctors","aw"
+ .globl __CTOR_LIST__
+ .type __CTOR_LIST__,@object
+__CTOR_LIST__:
+
+# List of C++ destructors
+ .section ".dtors","aw"
+ .globl __DTOR_LIST__
+ .type __DTOR_LIST__,@object
+__DTOR_LIST__:
+
+# Head of __init function used for static constructors in Solaris
+ .section ".init","ax"
+ .align 2
+ .globl __init
+ .type __init,@function
+__init: stwu %r1,-16(%r1)
+ mflr %r0
+ stw %r31,12(%r1)
+ stw %r0,16(%r1)
+
+ bl _GLOBAL_OFFSET_TABLE_-4 # get the GOT address
+ mflr %r31
+
+# lwz %r3,_ex_shared0@got(%r31)
+# lwz %r4,-8(%r3) # _ex_register or 0
+# cmpi %cr0,%r4,0
+# beq .Lno_reg
+# mtlr %r4
+# blrl
+#.Lno_reg:
+
+# Head of __fini function used for static destructors in Solaris
+ .section ".fini","ax"
+ .align 2
+ .globl __fini
+ .type __fini,@function
+__fini: stwu %r1,-16(%r1)
+ mflr %r0
+ stw %r31,12(%r1)
+ stw %r0,16(%r1)
+
+ bl _GLOBAL_OFFSET_TABLE_-4 # get the GOT address
+ mflr %r31
+
+# _environ and its evil twin environ, pointing to the environment
+ .section ".sdata","aw"
+ .align 2
+ .globl _environ
+ .space 4
+ .weak environ
+ .set environ,_environ
diff --git a/gnu/usr.bin/gcc/config/rs6000/sol-cn.asm b/gnu/usr.bin/gcc/config/rs6000/sol-cn.asm
new file mode 100644
index 00000000000..2bc992e1391
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/sol-cn.asm
@@ -0,0 +1,82 @@
+# crtn.s for solaris
+
+# Copyright (C) 1996 Free Software Foundation, Inc.
+# Written By Michael Meissner
+#
+# 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 ending points for the .got* and other
+# special sections. It is linked in last after other modules.
+
+ .file "scrtn.s"
+ .ident "GNU C scrtn.s"
+
+# Default versions of exception handling register/deregister
+ .weak _ex_register
+ .weak _ex_deregister
+ .set _ex_register,0
+ .set _ex_deregister,0
+
+# End list of C++ constructors
+ .section ".ctors","aw"
+ .globl __CTOR_END__
+ .type __CTOR_END__,@object
+__CTOR_END__:
+
+# End list of C++ destructors
+ .section ".dtors","aw"
+ .globl __DTOR_END__
+ .type __DTOR_END__,@object
+__DTOR_END__:
+
+ .section ".text"
+ .globl _ex_text1
+_ex_text1:
+
+ .section ".exception_ranges","aw"
+ .globl _ex_range1
+_ex_range1:
+
+# Tail of __init used for static constructors in Solaris
+ .section ".init","ax"
+ lwz %r0,16(%r1)
+ lwz %r31,12(%r1)
+ mtlr %r0
+ addi %r1,%r1,16
+ blr
+
+# Tail of __fini used for static destructors in Solaris
+ .section ".fini","ax"
+ lwz %r0,16(%r1)
+ lwz %r31,12(%r1)
+ mtlr %r0
+ addi %r1,%r1,16
+ blr
diff --git a/gnu/usr.bin/gcc/config/rs6000/sol2.h b/gnu/usr.bin/gcc/config/rs6000/sol2.h
new file mode 100644
index 00000000000..0a73c4d26d5
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/sol2.h
@@ -0,0 +1,178 @@
+/* Definitions of target machine for GNU compiler,
+ for IBM RS/6000 running AIX version 3.1.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by David Reese (Dave.Reese@East.Sun.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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "rs6000/sysv4le.h"
+
+/* Default ABI to use */
+#undef RS6000_ABI_NAME
+#define RS6000_ABI_NAME "solaris"
+
+#undef ASM_CPU_SPEC
+#define ASM_CPU_SPEC "-le -s"
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_POWERPC | \
+ MASK_NEW_MNEMONICS | \
+ MASK_LITTLE_ENDIAN | \
+ MASK_REGNAMES)
+
+#undef LIB_DEFAULT_SPEC
+#define LIB_DEFAULT_SPEC "%(lib_solaris)"
+
+#undef STARTFILE_DEFAULT_SPEC
+#define STARTFILE_DEFAULT_SPEC "%(startfile_solaris)"
+
+#undef ENDFILE_DEFAULT_SPEC
+#define ENDFILE_DEFAULT_SPEC "%(endfile_solaris)"
+
+#undef LINK_START_DEFAULT_SPEC
+#define LINK_START_DEFAULT_SPEC "%(link_start_solaris)"
+
+#undef CPP_SPEC
+#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
+%(cpp_sysv) %(cpp_endian) %(cpp_cpu) \
+%{mmvme: %(cpp_os_mvme) } \
+%{msim: %(cpp_os_sim) } \
+%{mcall-linux: %(cpp_os_linux) } \
+%{mcall-solaris: %(cpp_os_solaris) } \
+%{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(cpp_os_default) }}}}"
+
+#undef CPP_OS_DEFAULT_SPEC
+#define CPP_OS_DEFAULT_SPEC "%(cpp_os_solaris)"
+
+#undef LINK_OS_DEFAULT_SPEC
+#define LINK_OS_DEFAULT_SPEC "%(link_os_solaris)"
+
+#undef CPP_ENDIAN_LITTLE_SPEC
+#define CPP_ENDIAN_LITTLE_SPEC CPP_ENDIAN_SOLARIS_SPEC
+
+/* Don't turn -B into -L if the argument specifies a relative file name. */
+#undef RELATIVE_PREFIX_NOT_LINKDIR
+
+#define DEFAULT_PCC_STRUCT_RETURN 0
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (PowerPC Solaris)");
+
+
+/* Macros to check register numbers against specific register classes. */
+
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+
+#if 0
+#undef ASM_OUTPUT_ALIGNED_LOCAL
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
+do { \
+ fprintf ((FILE), "\t%s\t", ".lcomm"); \
+ assemble_name ((FILE), (NAME)); \
+ fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
+} while (0)
+#endif
+
+/* Like block addresses, stabs line numbers are relative to the
+ current function. */
+
+/* use .stabd instead of .stabn */
+
+#define ASM_STABN_OP ".stabd"
+
+#undef ASM_OUTPUT_SOURCE_LINE
+#define ASM_OUTPUT_SOURCE_LINE(file, line) \
+do \
+ { \
+ static int sym_lineno = 1; \
+ char *_p; \
+ fprintf (file, "\t.stabd 68,0,%d,.LM%d-", \
+ line, sym_lineno); \
+ STRIP_NAME_ENCODING (_p, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
+ assemble_name (file, _p); \
+ fprintf (file, "\n.LM%d:\n", sym_lineno); \
+ sym_lineno += 1; \
+ } \
+while (0)
+
+/* This is how to output an assembler line defining a `double' constant. */
+
+#undef ASM_OUTPUT_DOUBLE
+#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
+ { \
+ if (REAL_VALUE_ISINF (VALUE) \
+ || REAL_VALUE_ISNAN (VALUE) \
+ || REAL_VALUE_MINUS_ZERO (VALUE)) \
+ { \
+ long t[2]; \
+ REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \
+ fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n", \
+ t[0] & 0xffffffff, t[1] & 0xffffffff); \
+ } \
+ else \
+ { \
+ char str[30]; \
+ REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", str); \
+ fprintf (FILE, "\t.double %s\n", str); \
+ } \
+ }
+
+/* This is how to output an assembler line defining a `float' constant. */
+
+#undef ASM_OUTPUT_FLOAT
+#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
+ { \
+ if (REAL_VALUE_ISINF (VALUE) \
+ || REAL_VALUE_ISNAN (VALUE) \
+ || REAL_VALUE_MINUS_ZERO (VALUE)) \
+ { \
+ long t; \
+ REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
+ fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff); \
+ } \
+ else \
+ { \
+ char str[30]; \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \
+ fprintf (FILE, "\t.float %s\n", str); \
+ } \
+ }
+
+
+/* Sun-ppc assembler does not permit '.' in some symbol names.
+ Use 'name_.labelno' instead. */
+#undef ASM_FORMAT_PRIVATE_NAME
+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
+( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
+ sprintf ((OUTPUT), "%s_.%d", (NAME), (LABELNO)))
+
+
+/* Define this macro as a C expression for the initializer of an
+ array of string to tell the driver program which options are
+ defaults for this target and thus do not need to be handled
+ specially when using `MULTILIB_OPTIONS'.
+
+ Do not define this macro if `MULTILIB_OPTIONS' is not defined in
+ the target makefile fragment or if none of the options listed in
+ `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
+
+#undef MULTILIB_DEFAULTS
+#define MULTILIB_DEFAULTS { "mlittle", "mcall-solaris" }
+
+#define STDC_0_IN_SYSTEM_HEADERS
diff --git a/gnu/usr.bin/gcc/config/rs6000/t-ppccomm b/gnu/usr.bin/gcc/config/rs6000/t-ppccomm
new file mode 100644
index 00000000000..c6f9b6c7629
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/t-ppccomm
@@ -0,0 +1,73 @@
+# Common support for PowerPC eabi, System V targets.
+
+# Do not build libgcc1.
+LIBGCC1 =
+CROSS_LIBGCC1 =
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so... [taken from t-sparclite]
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c eabi.S eabi-ctors.c tramp.S
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+eabi.S: $(srcdir)/config/rs6000/eabi.asm
+ cat $(srcdir)/config/rs6000/eabi.asm > eabi.S
+
+eabi-ctors.c: $(srcdir)/config/rs6000/eabi-ctors.c
+ cat $(srcdir)/config/rs6000/eabi-ctors.c > eabi-ctors.c
+
+tramp.S: $(srcdir)/config/rs6000/tramp.asm
+ cat $(srcdir)/config/rs6000/tramp.asm > tramp.S
+
+# Switch synonyms
+MULTILIB_MATCHES_FLOAT = msoft-float=mcpu?403 msoft-float=mcpu?821 msoft-float=mcpu?860
+MULTILIB_MATCHES_ENDIAN = mlittle=mlittle-endian mbig=mbig-endian
+MULTILIB_MATCHES_SYSV = mcall-sysv=mcall-sysv-eabi mcall-sysv=mcall-sysv-noeabi
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+EXTRA_MULTILIB_PARTS = ecrti$(objext) ecrtn$(objext) scrt0$(objext) scrti$(objext) scrtn$(objext)
+
+# We build {e,s}crti.o, {e,s}crtn.o, and scrt0.o which serve to add begin and
+# end labels to all of the special sections used when we link using gcc.
+
+# Assemble startup files.
+ecrti.S: $(srcdir)/config/rs6000/eabi-ci.asm
+ cat $(srcdir)/config/rs6000/eabi-ci.asm >ecrti.S
+
+ecrtn.S: $(srcdir)/config/rs6000/eabi-cn.asm
+ cat $(srcdir)/config/rs6000/eabi-cn.asm >ecrtn.S
+
+scrti.S: $(srcdir)/config/rs6000/sol-ci.asm
+ cat $(srcdir)/config/rs6000/sol-ci.asm >scrti.S
+
+scrtn.S: $(srcdir)/config/rs6000/sol-cn.asm
+ cat $(srcdir)/config/rs6000/sol-cn.asm >scrtn.S
+
+scrt0.c: $(srcdir)/config/rs6000/sol-c0.c
+ cat $(srcdir)/config/rs6000/sol-c0.c >scrt0.c
+
+# Build multiple copies of ?crt{i,n}.o, one for each target switch.
+$(T)ecrti$(objext): ecrti.S
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c ecrti.S -o $(T)ecrti$(objext)
+
+$(T)ecrtn$(objext): ecrtn.S
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c ecrtn.S -o $(T)ecrtn$(objext)
+
+$(T)scrti$(objext): scrti.S
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c scrti.S -o $(T)scrti$(objext)
+
+$(T)scrtn$(objext): scrtn.S
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c scrtn.S -o $(T)scrtn$(objext)
+
+$(T)scrt0$(objext): scrt0.c
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c scrt0.c -o $(T)scrt0$(objext)
+
+# It is important that crtbegin.o, etc., aren't surprised by stuff in .sdata.
+CRTSTUFF_T_CFLAGS = -msdata=none
+CRTSTUFF_T_CFLAGS_S = -fpic -msdata=none
diff --git a/gnu/usr.bin/gcc/config/rs6000/t-ppcos b/gnu/usr.bin/gcc/config/rs6000/t-ppcos
new file mode 100644
index 00000000000..480665a8937
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/t-ppcos
@@ -0,0 +1,12 @@
+# Target config file for a System V based system (Solaris, GNU/Linux, Netbsd)
+# with gas.
+
+# Build libgcc.a with different options. With gas, build pic libraries
+# as well no floating point
+MULTILIB_OPTIONS = msoft-float fPIC
+MULTILIB_DIRNAMES = nof pic
+MULTILIB_EXCEPTIONS =
+MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} \
+ fPIC=mrelocatable-lib \
+ fPIC=mrelocatable \
+ fPIC=fpic
diff --git a/gnu/usr.bin/gcc/config/rs6000/t-winnt b/gnu/usr.bin/gcc/config/rs6000/t-winnt
new file mode 100644
index 00000000000..f58aefed523
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/t-winnt
@@ -0,0 +1,35 @@
+# Do not build libgcc1.
+LIBGCC1 =
+CROSS_LIBGCC1 =
+
+EXTRA_PARTS = crti.o crtn.o
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so... [taken from t-sparclite]
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c ntstack.S
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+ntstack.S: $(srcdir)/config/rs6000/ntstack.asm
+ cat $(srcdir)/config/rs6000/ntstack.asm > ntstack.S
+
+# For NT we build crti.o and crtn.o which serve to add begin and
+# end labels for the static constructors and destructors.
+
+# Assemble startup files.
+crti.s: $(srcdir)/config/rs6000/nt-ci.asm
+ cat $(srcdir)/config/rs6000/nt-ci.asm >crti.s
+
+crtn.s: $(srcdir)/config/rs6000/nt-cn.asm
+ cat $(srcdir)/config/rs6000/nt-cn.asm >crtn.s
+
+crti.o: crti.s
+ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crti.o crti.s
+
+crtn.o: crtn.s
+ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crtn.o crtn.s
diff --git a/gnu/usr.bin/gcc/config/rs6000/t-xnewas b/gnu/usr.bin/gcc/config/rs6000/t-xnewas
new file mode 100644
index 00000000000..285f8259d07
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/t-xnewas
@@ -0,0 +1,58 @@
+# Same as t-newas, except don't build libgcc1-test. This is because
+# the compiler emits code to call external functions to save the
+# arguments that are in libc, but since libgcc1-test is linked without
+# libc, they will show up as errors.
+LIBGCC1_TEST =
+
+# Do not build libgcc1.
+LIBGCC1 =
+CROSS_LIBGCC1 =
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so... [taken from t-sparclite]
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+# Build the libraries for both hard and soft floating point and all of the
+# different processor models
+
+MULTILIB_OPTIONS = msoft-float \
+ mcpu=common/mcpu=power/mcpu=powerpc
+
+MULTILIB_DIRNAMES = soft-float \
+ common power powerpc
+
+MULTILIB_MATCHES = msoft-float=mcpu?403 \
+ mcpu?power=mpower \
+ mcpu?power=mrios1 \
+ mcpu?power=mcpu?rios1 \
+ mcpu?power=mcpu?rsc \
+ mcpu?power=mcpu?rsc1 \
+ mcpu?power=mpower2 \
+ mcpu?power=mrios2 \
+ mcpu?power=mcpu=rios2 \
+ mcpu?powerpc=mcpu?601 \
+ mcpu?powerpc=mcpu?602 \
+ mcpu?powerpc=mcpu?603 \
+ mcpu?powerpc=mcpu?603e \
+ mcpu?powerpc=mcpu?604 \
+ mcpu?powerpc=mcpu?620 \
+ mcpu?powerpc=mcpu?403 \
+ mcpu?powerpc=mpowerpc \
+ mcpu?powerpc=mpowerpc-gpopt \
+ mcpu?powerpc=mpowerpc-gfxopt
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+
+# Aix 3.2.x needs milli.exp for -mcpu=common
+EXTRA_PARTS = milli.exp
+milli.exp: $(srcdir)/config/rs6000/milli.exp
+ rm -f milli.exp
+ cp $(srcdir)/config/rs6000/milli.exp ./milli.exp
diff --git a/gnu/usr.bin/gcc/config/rs6000/t-xrs6000 b/gnu/usr.bin/gcc/config/rs6000/t-xrs6000
new file mode 100644
index 00000000000..f5d34d658b7
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/t-xrs6000
@@ -0,0 +1,28 @@
+# Same as t-rs6000, except don't build libgcc1-test. This is because
+# the compiler emits code to call external functions to save the
+# arguments that are in libc, but since libgcc1-test is linked without
+# libc, they will show up as errors.
+LIBGCC1_TEST =
+
+# Do not build libgcc1.
+LIBGCC1 =
+CROSS_LIBGCC1 =
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so... [taken from t-sparclite]
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+# Build the libraries for both hard and soft floating point
+
+MULTILIB_OPTIONS = msoft-float
+MULTILIB_DIRNAMES = soft-float
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
diff --git a/gnu/usr.bin/gcc/config/rs6000/tramp.asm b/gnu/usr.bin/gcc/config/rs6000/tramp.asm
new file mode 100644
index 00000000000..47ab7d65b1f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/tramp.asm
@@ -0,0 +1,120 @@
+/* Special support for trampolines
+ *
+ * Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ * Written By Michael Meissner
+ *
+ * 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.
+ */
+
+/* Set up trampolines */
+
+ .file "tramp.asm"
+ .section ".text"
+ #include "ppc-asm.h"
+
+ .globl __trampoline_initial
+ .type __trampoline_initial,@object
+ .align 2
+__trampoline_initial:
+ mflr r0
+ bl 1f
+.Lfunc = .-__trampoline_initial
+ .long 0 /* will be replaced with function address */
+.Lchain = .-__trampoline_initial
+ .long 0 /* will be replaced with static chain */
+1: mflr r11
+ mtlr r0
+ lwz r0,0(r11) /* function address */
+ lwz r11,4(r11) /* static chain */
+ mtctr r0
+ bctr
+
+__trampoline_size = .-__trampoline_initial
+ .size __trampoline_initial,__trampoline_size
+
+ .section ".got2","aw"
+.LCTOC1 = .+32768
+.Ltramp = .-.LCTOC1
+ .long __trampoline_initial-4
+
+ .section ".text"
+.LCL0:
+ .long .LCTOC1-.LCF0
+
+/* R3 = stack address to store trampoline */
+/* R4 = length of trampoline area */
+/* R5 = function address */
+/* R6 = static chain */
+
+FUNC_START(__trampoline_setup)
+ mflr r0 /* save return address */
+ bl .LCF0 /* load up __trampoline_initial into r7 */
+.LCF0:
+ mflr r11
+ lwz r12,(.LCL0-.LCF0)(r11)
+ add r11,r12,r11
+ lwz r7,.Ltramp(r11) /* trampoline address -4 */
+
+ li r8,__trampoline_size /* verify that the trampoline is big enough */
+ cmpw cr1,r8,r4
+ srwi r4,r4,2 /* # words to move */
+ addi r9,r3,-4 /* adjust pointer for lwzu */
+ mtctr r4
+ blt cr1,.Labort
+
+ mtlr r0
+
+ /* Copy the instructions to the stack */
+.Lmove:
+ lwzu r10,4(r7)
+ stwu r10,4(r9)
+ bdnz .Lmove
+
+ /* Store correct function and static chain */
+ stw r5,.Lfunc(r3)
+ stw r6,.Lchain(r3)
+
+ /* Now flush both caches */
+ mtctr r4
+.Lcache:
+ icbi 0,r3
+ dcbf 0,r3
+ addi r3,r3,4
+ bdnz .Lcache
+
+ /* Finally synchronize things & return */
+ sync
+ isync
+ blr
+
+.Labort:
+ bl abort
+FUNC_END(__trampoline_setup)
+/* END CYGNUS LOCAL -- waiting for FSF sources to be restored/meissner */
diff --git a/gnu/usr.bin/gcc/config/rs6000/vxppc.h b/gnu/usr.bin/gcc/config/rs6000/vxppc.h
new file mode 100644
index 00000000000..0dddc498325
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/vxppc.h
@@ -0,0 +1,63 @@
+/* Definitions of target machine for GNU compiler. Vxworks PowerPC version.
+ Copyright (C) 1996 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 just exists to give specs for the PowerPC running on VxWorks. */
+
+#include "rs6000/sysv4.h"
+
+#undef CPP_SPEC
+#define CPP_SPEC "\
+%{posix: -D_POSIX_SOURCE} \
+%{!mcpu*: \
+ %{mpowerpc*: -D_ARCH_PPC -DCPU=PPC603} \
+ %{!mno-powerpc: -D_ARCH_PPC -DCPU=PPC603}} \
+%{mcpu=powerpc: -D_ARCH_PPC -DCPU=PPC603} \
+%{mcpu=403: -D_ARCH_PPC -DCPU=PPC403} \
+%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR -DCPU=PPC601} \
+%{mcpu=603: -D_ARCH_PPC -DCPU=PPC603} \
+%{mcpu=604: -D_ARCH_PPC -DCPU=PPC604}"
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "\
+-D__vxworks -D__vxworks__ -Asystem(vxworks) -Asystem(embedded) \
+-Acpu(powerpc) -Amachine(powerpc)"
+
+/* VxWorks does all the library stuff itself. */
+
+#undef LIB_SPEC
+#define LIB_SPEC ""
+
+/* VxWorks uses object files, not loadable images. make linker just
+ combine objects. */
+
+#undef LINK_SPEC
+#define LINK_SPEC "-r"
+
+/* VxWorks provides the functionality of crt0.o and friends itself. */
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC ""
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC ""
+
+/* We use stabs-in-elf for debugging */
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
diff --git a/gnu/usr.bin/gcc/config/rs6000/win-nt.h b/gnu/usr.bin/gcc/config/rs6000/win-nt.h
new file mode 100644
index 00000000000..2fcf44647d2
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/win-nt.h
@@ -0,0 +1,478 @@
+/* Definitions of target machine for GNU compiler, for PowerPC
+ running Windows/NT.
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+
+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. */
+
+/* Say this is Windows/NT for the other config files. */
+#define WINDOWS_NT 1
+#define COFF_WITH_PE 1
+
+/* Default ABI to compile code for */
+#define DEFAULT_ABI ABI_NT
+
+#include "rs6000/powerpc.h"
+
+/* Pseudo target that we can test in the md file. */
+#undef TARGET_WINDOWS_NT
+#define TARGET_WINDOWS_NT 1
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-DWIN32 -D_WIN32 \
+ -DWINNT -D__STDC__=0 -DALMOST_STDC \
+ -D_POWER -D_ARCH_PPC -D__PPC__ -Asystem(winnt) -Acpu(powerpc) -Amachine(powerpc)"
+
+#if 0
+#include "winnt/win-nt.h"
+#endif
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{mwindows:-subsystem:windows -entry:WinMainCRTStartup \
+ USER32.LIB GDI32.LIB COMDLG32.LIB WINSPOOL.LIB} \
+ %{!mwindows:-subsystem console -e mainCRTStartup} \
+ %{mcrtmt:LIBCMT.LIB KERNEL32.LIB} %{!mcrtmt:-lkernel32 -lcygwin} \
+ %{v}"
+
+#undef LINK_SPEC
+#define LINK_SPEC "%{v:-V}"
+
+/* Allow switches specified in LIB_SPEC, but don't do anything with them
+ in the compiler. */
+#undef SUBTARGET_SWITCHES
+#define SUBTARGET_SWITCHES \
+ { "windows", 0 }, \
+ { "crtmt", 0 },
+
+#undef XCOFF_DEBUGGING_INFO
+
+/* this is pure coff, not xcoff */
+#define SDB_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO
+
+#undef SDB_DELIM
+#define SDB_DELIM ";"
+
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+#undef PROCESSOR_DEFAULT
+#define PROCESSOR_DEFAULT PROCESSOR_POWERPC
+
+/* NT always runs little endian */
+#undef BYTES_BIG_ENDIAN
+#define BYTES_BIG_ENDIAN 0
+
+#undef WORDS_BIG_ENDIAN
+#define WORDS_BIG_ENDIAN 0
+
+/* Define cutoff for using external functions to save floating point.
+ Currently on NT, always use inline stores */
+#undef FP_SAVE_INLINE
+#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64)
+
+/* Note, little endian systems trap on unaligned addresses, so never
+ turn off strict alignment in that case. */
+
+#undef STRICT_ALIGNMENT
+#define STRICT_ALIGNMENT 1
+
+/* Align stack to 16 byte boundaries */
+#undef STACK_BOUNDARY
+#define STACK_BOUNDARY 128
+
+/* No data type wants to be aligned rounder than this. */
+#undef BIGGEST_ALIGNMENT
+#define BIGGEST_ALIGNMENT 128
+
+/* NT aligns internal doubles in structures on dword boundaries. */
+#undef BIGGEST_FIELD_ALIGNMENT
+#define BIGGEST_FIELD_ALIGNMENT 64
+
+#undef ADJUST_FIELD_ALIGN
+#undef ROUND_TYPE_ALIGN
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (PowerPC PE)");
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC)
+
+#undef PROCESSOR_DEFAULT
+#define PROCESSOR_DEFAULT PROCESSOR_PPC601
+
+/* Address to save the TOC register */
+#undef RS6000_SAVE_TOC
+#define RS6000_SAVE_TOC plus_constant (virtual_incoming_args_rtx, -RS6000_SAVE_AREA - 8)
+
+/* Windows NT specifies that r13 is reserved to the OS, so it is not available
+ to the normal user. */
+
+#undef FIXED_R13
+#define FIXED_R13 1
+
+/* This says how to output an assembler line
+ to define a global common symbol. */
+
+#undef ASM_OUTPUT_ALIGNED_COMMON
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNMENT) \
+ do { fputs ("\t.comm \t", (FILE)); \
+ assemble_name ((FILE), (NAME)); \
+ if ( (SIZE) > 4) \
+ fprintf ((FILE), ",%d,%d\n", (SIZE), 3); \
+ else \
+ fprintf( (FILE), ",%d\n", (SIZE)); \
+ } while (0)
+
+#undef ASM_OUTPUT_ALIGNED_LOCAL
+
+/* This says how to output an assembler line
+ to define a global common symbol. */
+
+#undef ASM_OUTPUT_COMMON
+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
+ do { fputs ("\t.comm \t", (FILE)); \
+ assemble_name ((FILE), (NAME)); \
+ fprintf ((FILE), ",%d\n", (SIZE)); } while (0)
+
+/* This says how to output an assembler line
+ to define an aligned local common symbol. */
+
+#undef ASM_OUTPUT_ALIGNED_LOCAL
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
+do { \
+ bss_section (); \
+ ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT)); \
+ ASM_OUTPUT_LABEL (FILE, NAME); \
+ ASM_OUTPUT_SKIP (FILE, SIZE); \
+} while (0)
+
+/* Describe how to emit uninitialized external linkage items */
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+do { \
+ ASM_GLOBALIZE_LABEL (FILE, NAME); \
+ ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \
+} while (0)
+
+/* This says out to put a global symbol in the BSS section */
+#undef ASM_OUTPUT_ALIGNED_BSS
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+ asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
+
+
+/* Stuff to force fit us into the Motorola PPC assembler */
+
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) \
+do { \
+ output_file_directive ((FILE), main_input_filename); \
+ rs6000_file_start (FILE, TARGET_CPU_DEFAULT); \
+ data_section (); \
+} while (0)
+
+#undef ASM_FILE_END
+
+#undef ASM_DECLARE_FUNCTION_NAME
+#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
+{ \
+ tree exception_args; \
+ int i; \
+ \
+ if (TREE_PUBLIC (DECL)) \
+ { \
+ fprintf (FILE, "\t.globl .."); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, "\n"); \
+ } \
+ \
+ fprintf (FILE, "\n#\tFunction: '.."); \
+ assemble_name (FILE, NAME); \
+ fputs ("'\n", FILE); \
+ fputs ("#\tText in section: <default>\n\n", FILE); \
+ fputs ("#\tSetup MS Structured-Exception-Handling\n", FILE); \
+ fputs ("\t.pdata\n", FILE); \
+ fputs ("\t.align 2\n", FILE); \
+ fputs ("\t.ualong ..", FILE); \
+ assemble_name (FILE, NAME); \
+ fputs (",", FILE); \
+ assemble_name (FILE, NAME); \
+ fputs (".e,", FILE); \
+ exception_args = lookup_attribute ("exception", \
+ TYPE_ATTRIBUTES (TREE_TYPE (DECL))); \
+ \
+ if (exception_args) \
+ exception_args = TREE_VALUE (exception_args); \
+ \
+ for (i = 0; i < 2; i++) \
+ { \
+ if (!exception_args) \
+ fputs ("0,", FILE); \
+ else \
+ { \
+ tree field = TREE_VALUE (exception_args); \
+ exception_args = TREE_PURPOSE (exception_args); \
+ if (TREE_CODE (field) == STRING_CST) \
+ fprintf (FILE, "%.*s,", TREE_STRING_LENGTH (field), \
+ TREE_STRING_POINTER (field)); \
+ else if (TREE_CODE (field) == IDENTIFIER_NODE) \
+ fprintf (FILE, "%.*s,", IDENTIFIER_LENGTH (field), \
+ IDENTIFIER_POINTER (field)); \
+ else \
+ abort (); \
+ } \
+ } \
+ \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, ".b\n\n"); \
+ fprintf (FILE, "#\tSwitch to the relocation section\n"); \
+ fprintf (FILE, "\t.reldata\n"); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, ":\n"); \
+ fprintf (FILE, "\t.ualong .."); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, ",.toc\n"); \
+ \
+ if (lookup_attribute ("dllexport", \
+ TYPE_ATTRIBUTES (TREE_TYPE (DECL)))) \
+ { \
+ fprintf (FILE, "\t.globl __imp_"); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, "\n__imp_"); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, ":\n\t.ulong "); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, "\n"); \
+ } \
+ \
+ fprintf (FILE, "\t.section .text\n\t.align 2\n.."); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, ":\n"); \
+ fprintf (FILE, "\t.function\t.."); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, "\n"); \
+}
+
+/* This is how to output an assembler line defining a `double' constant. */
+
+#undef ASM_OUTPUT_DOUBLE
+#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
+ { \
+ if (REAL_VALUE_ISINF (VALUE) \
+ || REAL_VALUE_ISNAN (VALUE) \
+ || REAL_VALUE_MINUS_ZERO (VALUE)) \
+ { \
+ long t[2]; \
+ REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \
+ fprintf (FILE, "\t.ualong 0x%lx\n\t.long 0x%lx\n", \
+ t[0] & 0xffffffff, t[1] & 0xffffffff); \
+ } \
+ else \
+ { \
+ char str[30]; \
+ REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", str); \
+ fprintf (FILE, "\t.double %s\n", str); \
+ } \
+ }
+
+/* This is how to output an assembler line defining a `float' constant. */
+
+#undef ASM_OUTPUT_FLOAT
+#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
+ { \
+ if (REAL_VALUE_ISINF (VALUE) \
+ || REAL_VALUE_ISNAN (VALUE) \
+ || REAL_VALUE_MINUS_ZERO (VALUE)) \
+ { \
+ long t; \
+ REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
+ fprintf (FILE, "\t.ualong 0x%lx\n", t & 0xffffffff); \
+ } \
+ else \
+ { \
+ char str[30]; \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \
+ fprintf (FILE, "\t.float %s\n", str); \
+ } \
+ }
+
+/* Output before instructions. */
+#undef TEXT_SECTION_ASM_OP
+#define TEXT_SECTION_ASM_OP "\t.text"
+
+/* Output before writable data. */
+#undef DATA_SECTION_ASM_OP
+#define DATA_SECTION_ASM_OP "\t.data"
+
+/* Output to the bss section. */
+#undef BSS_SECTION_ASM_OP
+#define BSS_SECTION_ASM_OP "\t.section .bss"
+
+/* Define the extra sections we need. We define a dummy TOC section,
+ plus sections to hold the list of static constructors (.ctors) and
+ destructors (.dtors). */
+
+#undef READONLY_DATA_SECTION
+#undef EXTRA_SECTIONS
+#define EXTRA_SECTIONS in_toc, in_ctors, in_dtors
+
+/* Define the routines to implement these extra sections. */
+
+#undef EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS \
+ CTORS_SECTION_FUNCTION \
+ DTORS_SECTION_FUNCTION \
+ TOC_SECTION_FUNCTION \
+
+#define TOC_SECTION_FUNCTION \
+void \
+toc_section () \
+{ \
+}
+
+#define CTORS_SECTION_ASM_OP ".section\t.ctors"
+#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_ASM_OP ".section\t.dtors"
+#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; \
+ } \
+}
+
+#undef SELECT_SECTION
+#undef SELECT_RTX_SECTION
+
+/* Make sure __main gets called */
+#define INVOKE__main 1
+
+/* A C statement (sans semicolon) to output an element in the table of
+ global constructors. */
+#undef ASM_OUTPUT_CONSTRUCTOR
+#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
+ do { \
+ ctors_section (); \
+ fprintf (FILE, "\t.ualong "); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, "\n"); \
+ } while (0)
+
+/* A C statement (sans semicolon) to output an element in the table of
+ global destructors. */
+#undef ASM_OUTPUT_DESTRUCTOR
+#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
+ do { \
+ dtors_section (); \
+ fprintf (FILE, "\t.ualong "); \
+ assemble_name (FILE, NAME); \
+ fprintf (FILE, "\n"); \
+ } while (0)
+
+
+/* Text to write out after a CALL that may be replaced by glue code by
+ the loader. The motorola asm demands that, for dll support, a .znop
+ be issued after a bl instruction, and the symbol on the .znop is the
+ symbol on the bl instruction */
+
+#undef RS6000_CALL_GLUE
+#define RS6000_CALL_GLUE "nop #\tFIXME: only works for non-dll calls."
+
+#define RS6000_CALL_GLUE2 ".znop "
+
+#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY
+
+/* Output something to declare an external symbol to the assembler. Most
+ assemblers don't need this. */
+
+#undef ASM_OUTPUT_EXTERNAL
+
+#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
+{ \
+ char *_name; \
+ rtx _symref = XEXP (DECL_RTL (DECL), 0); \
+ if ((TREE_CODE (DECL) == VAR_DECL \
+ || TREE_CODE (DECL) == FUNCTION_DECL) \
+ && (NAME)[strlen (NAME) - 1] != ']') \
+ { \
+ _name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \
+ strcpy (_name, XSTR (_symref, 0)); \
+ XSTR (_symref, 0) = _name; \
+ } \
+ else \
+ _name = XSTR (_symref, 0); \
+ \
+ if (DECL_FUNCTION_CODE (DECL) == 0) \
+ { \
+ fputs ("\t.extern ", FILE); \
+ assemble_name (FILE, _name); \
+ putc ('\n', FILE); \
+ if (TREE_CODE (DECL) == FUNCTION_DECL) \
+ { \
+ fputs ("\t.extern ..", FILE); \
+ assemble_name (FILE, _name); \
+ putc ('\n', FILE); \
+ } \
+ } \
+}
+
+/* Similar, but for libcall. We only have to worry about the function name,
+ not that of the descriptor. */
+
+#undef ASM_OUTPUT_EXTERNAL_LIBCALL
+
+#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
+{ fprintf (FILE, "\t.extern .."); \
+ assemble_name (FILE, XSTR (FUN, 0)); \
+ fprintf (FILE, "\n"); \
+}
+
+/* The prefix to add to user-visible assembler symbols. */
+
+#define USER_LABEL_PREFIX ".."
+
+/* Eliminate AIX style constant pool processing */
+#undef LEGITIMATE_CONSTANT_POOL_BASE_P
+#define LEGITIMATE_CONSTANT_POOL_BASE_P(X) 0
+
+#undef LEGITIMATE_CONSTANT_POOL_ADDRESS_P
+#define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X) 0
+
+#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY
+
+#undef ASM_IDENTIFY_GCC
+#define ASM_IDENTIFY_GCC(x)
+
+/* Output assembler code for a block containing the constant parts
+ of a trampoline, leaving space for the variable parts.
+
+ The trampoline should set the static chain pointer to value placed
+ into the trampoline and should branch to the specified routine. */
+#define TRAMPOLINE_TEMPLATE(FILE) rs6000_trampoline_template (FILE)
diff --git a/gnu/usr.bin/gcc/config/rs6000/x-cygwin32 b/gnu/usr.bin/gcc/config/rs6000/x-cygwin32
new file mode 100644
index 00000000000..5e796a0e916
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/x-cygwin32
@@ -0,0 +1,4 @@
+# Don't run fixproto
+STMP_FIXPROTO =
+# Don't need collect2
+USE_COLLECT2 =
diff --git a/gnu/usr.bin/gcc/config/rs6000/xm-cygwin32.h b/gnu/usr.bin/gcc/config/rs6000/xm-cygwin32.h
new file mode 100644
index 00000000000..677254b371c
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/rs6000/xm-cygwin32.h
@@ -0,0 +1,26 @@
+/* Configuration for GNU C-compiler for hosting on Windows NT.
+ using a unix style C library.
+ Copyright (C) 1995, 1997 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+#define NO_STAB_H
+
+#include "rs6000/xm-rs6000.h"
+
+#define EXECUTABLE_SUFFIX ".exe"
diff --git a/gnu/usr.bin/gcc/config/sh/elf.h b/gnu/usr.bin/gcc/config/sh/elf.h
new file mode 100644
index 00000000000..a56077e544e
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sh/elf.h
@@ -0,0 +1,122 @@
+/* Definitions of target machine for gcc for Hitachi Super-H using ELF.
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ Contributed by Ian Lance Taylor <ian@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. */
+
+/* Mostly like the regular SH configuration. */
+#include "sh/sh.h"
+
+/* No SDB debugging info. */
+#undef SDB_DEBUGGING_INFO
+
+/* Undefine some macros defined in both sh.h and svr4.h. */
+#undef IDENT_ASM_OP
+#undef ASM_FILE_END
+#undef ASM_OUTPUT_SOURCE_LINE
+#undef DBX_OUTPUT_MAIN_SOURCE_FILE_END
+#undef CTORS_SECTION_ASM_OP
+#undef DTORS_SECTION_ASM_OP
+#undef ASM_OUTPUT_SECTION_NAME
+#undef ASM_OUTPUT_CONSTRUCTOR
+#undef ASM_OUTPUT_DESTRUCTOR
+#undef ASM_DECLARE_FUNCTION_NAME
+#undef PREFERRED_DEBUGGING_TYPE
+
+/* Be ELF-like. */
+#include "svr4.h"
+
+/* The prefix to add to user-visible assembler symbols.
+ Note that svr4.h redefined it from the original value (that we want)
+ in sh.h */
+
+#undef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX "_"
+
+#undef LOCAL_LABEL_PREFIX
+#define LOCAL_LABEL_PREFIX "."
+
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) do { \
+ output_file_directive ((FILE), main_input_filename); \
+ if (TARGET_LITTLE_ENDIAN) \
+ fprintf ((FILE), "\t.little\n"); \
+} while (0)
+
+
+
+/* Let code know that this is ELF. */
+#define CPP_PREDEFINES "-D__sh__ -D__ELF__ -Acpu(sh) -Amachine(sh)"
+
+/* Pass -ml and -mrelax to the assembler and linker. */
+#undef ASM_SPEC
+#define ASM_SPEC "%{ml:-little} %{mrelax:-relax}"
+
+#undef LINK_SPEC
+#define LINK_SPEC "%{ml:-m shlelf} %{mrelax:-relax}"
+
+/* svr4.h undefined DBX_REGISTER_NUMBER, so we need to define it
+ again. */
+#define DBX_REGISTER_NUMBER(REGNO) \
+ (((REGNO) >= 22 && (REGNO) <= 39) ? ((REGNO) + 1) : (REGNO))
+
+/* SH ELF, unlike most ELF implementations, uses underscores before
+ symbol names. */
+#undef ASM_OUTPUT_LABELREF
+#define ASM_OUTPUT_LABELREF(STREAM,NAME) \
+ asm_fprintf (STREAM, "%U%s", NAME)
+
+#undef ASM_GENERATE_INTERNAL_LABEL
+#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
+ sprintf ((STRING), "*%s%s%d", LOCAL_LABEL_PREFIX, (PREFIX), (NUM))
+
+#undef ASM_OUTPUT_INTERNAL_LABEL
+#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
+ asm_fprintf ((FILE), "%L%s%d:\n", (PREFIX), (NUM))
+
+#undef ASM_OUTPUT_SOURCE_LINE
+#define ASM_OUTPUT_SOURCE_LINE(file, line) \
+do \
+ { \
+ static int sym_lineno = 1; \
+ asm_fprintf ((file), ".stabn 68,0,%d,%LLM%d-", \
+ (line), sym_lineno); \
+ assemble_name ((file), \
+ XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
+ asm_fprintf ((file), "\n%LLM%d:\n", sym_lineno); \
+ sym_lineno += 1; \
+ } \
+while (0)
+
+#undef DBX_OUTPUT_MAIN_SOURCE_FILE_END
+#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
+do { \
+ text_section (); \
+ fprintf ((FILE), "\t.stabs \"\",%d,0,0,Letext\nLetext:\n", N_SO); \
+} while (0)
+
+/* Arrange to call __main, rather than using crtbegin.o and crtend.o
+ and relying on .init and .fini being executed at appropriate times. */
+#undef INIT_SECTION_ASM_OP
+#undef FINI_SECTION_ASM_OP
+#undef STARTFILE_SPEC
+#undef ENDFILE_SPEC
+
+/* HANDLE_SYSV_PRAGMA (defined by svr4.h) takes precedence over HANDLE_PRAGMA.
+ We want to use the HANDLE_PRAGMA from sh.h. */
+#undef HANDLE_SYSV_PRAGMA
diff --git a/gnu/usr.bin/gcc/config/sh/rtems.h b/gnu/usr.bin/gcc/config/sh/rtems.h
new file mode 100644
index 00000000000..2e864ad5c29
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sh/rtems.h
@@ -0,0 +1,28 @@
+/* Definitions for rtems targeting a SH using elf.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Joel Sherrill (joel@OARcorp.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 "sh/elf.h"
+
+/* Specify predefined symbols in preprocessor. */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-D__sh__ -D__ELF__ -Drtems -D__rtems__ \
+ -Asystem(rtems) -Acpu(sh) -Amachine(sh)"
diff --git a/gnu/usr.bin/gcc/config/sparc/aout.h b/gnu/usr.bin/gcc/config/sparc/aout.h
new file mode 100644
index 00000000000..478d710f82f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/aout.h
@@ -0,0 +1,26 @@
+/* Definitions of target machine for GNU compiler, for SPARC using a.out.
+ Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+ Contributed by Michael Tiemann (tiemann@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 "sparc/sparc.h" /* SPARC definitions */
+#include "aoutos.h" /* A.out definitions */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Dsparc -Acpu(sparc) -Amachine(sparc)"
diff --git a/gnu/usr.bin/gcc/config/sparc/elf.h b/gnu/usr.bin/gcc/config/sparc/elf.h
new file mode 100644
index 00000000000..70cb26a93be
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/elf.h
@@ -0,0 +1,42 @@
+/* Definitions of target machine for GNU compiler,
+ for SPARC running in an embedded environment using the ELF file format.
+ Copyright (C) 1997 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 "sol2.h"
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Dsparc -D__elf__ -Acpu(sparc) -Amachine(sparc)"
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
+
+/* Use the default. */
+#undef LINK_SPEC
+
+/* Don't set the target flags, this is done by the linker script */
+#undef LIB_SPEC
+#define LIB_SPEC ""
+
+/* FIXME: until fixed */
+#undef LONG_DOUBLE_TYPE_SIZE
+#define LONG_DOUBLE_TYPE_SIZE 64
diff --git a/gnu/usr.bin/gcc/config/sparc/linux-aout.h b/gnu/usr.bin/gcc/config/sparc/linux-aout.h
new file mode 100644
index 00000000000..7075b5fbe7c
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/linux-aout.h
@@ -0,0 +1,111 @@
+/* Definitions for SPARC running Linux-based GNU systems with a.out.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Eddie C. Dost (ecd@skynet.be)
+
+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 <aoutos.h>
+#include <sparc/sparc.h>
+
+/* Don't assume anything about the header files. */
+#define NO_IMPLICIT_EXTERN_C
+
+#undef HAVE_ATEXIT
+#define HAVE_ATEXIT
+
+/* GNU/Linux uses ctype from glibc.a. I am not sure how complete it is.
+ For now, we play safe. It may change later. */
+
+#if 0
+#undef MULTIBYTE_CHARS
+#define MULTIBYTE_CHARS 1
+#endif
+
+/* We need that too. */
+#define HANDLE_SYSV_PRAGMA
+
+#undef MD_EXEC_PREFIX
+#undef MD_STARTFILE_PREFIX
+
+/* 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)
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "%{pg:gcrt0.o%s} %{!pg:%{p:gcrt0.o%s} %{!p:crt0.o%s}} %{static:-static}"
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (sparc GNU/Linux with a.out)");
+
+#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 "-Dunix -Dsparc -Dlinux -Asystem(unix) -Asystem(posix)"
+
+#undef CPP_SUBTARGET_SPEC
+#define CPP_SUBTARGET_SPEC \
+"%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}"
+
+/* 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 GNU/Linux C library, please add
+ -lc_p or -ggdb to LDFLAGS at the link time, respectively. */
+#define LIB_SPEC \
+"%{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} %{!ggdb:-lc} %{ggdb:-lg}"
+#else
+#define LIB_SPEC \
+"%{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} \
+ %{!p:%{!pg:%{!g*:-lc} %{g*:-lg -static}}}"
+#endif
+
+#undef LINK_SPEC
+#define LINK_SPEC "-m sparclinux"
+
+/* The sun bundled assembler doesn't accept -Yd, (and neither does gas).
+ It's safe to pass -s always, even if -g is not used. */
+#undef ASM_SPEC
+#define ASM_SPEC \
+ "%{V} %{v:%{!V:-V}} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s %{fpic:-K PIC} %{fPIC:-K PIC}"
+
+#if 0
+/* Define for support of TFmode long double and REAL_ARITHMETIC.
+ Sparc ABI says that long double is 4 words. GNU/Linux does not support
+ long double yet. */
+#define LONG_DOUBLE_TYPE_SIZE 128
+#endif
diff --git a/gnu/usr.bin/gcc/config/sparc/linux.h b/gnu/usr.bin/gcc/config/sparc/linux.h
new file mode 100644
index 00000000000..9ce30d108ee
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/linux.h
@@ -0,0 +1,234 @@
+/* Definitions for SPARC running Linux-based GNU systems with ELF.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Eddie C. Dost (ecd@skynet.be)
+
+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
+
+/* Don't assume anything about the header files. */
+#define NO_IMPLICIT_EXTERN_C
+
+#undef HAVE_ATEXIT
+#define HAVE_ATEXIT
+
+/* GNU/Linux uses ctype from glibc.a. I am not sure how complete it is.
+ For now, we play safe. It may change later. */
+
+#if 0
+#undef MULTIBYTE_CHARS
+#define MULTIBYTE_CHARS 1
+#endif
+
+/* Use stabs instead of DWARF debug format. */
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+#include <sparc/sysv4.h>
+
+#undef MD_EXEC_PREFIX
+#undef MD_STARTFILE_PREFIX
+
+/* 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)
+
+/* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add
+ the GNU/Linux magical crtbegin.o file (see crtstuff.c) which
+ provides part of the support for getting C++ file-scope static
+ object constructed before entering `main'. */
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+ "%{!shared: \
+ %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
+ crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+
+/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
+ the GNU/Linux magical crtend.o file (see crtstuff.c) which
+ provides part of the support for getting C++ file-scope static
+ object constructed before entering `main', followed by a normal
+ GNU/Linux "finalizer" file, `crtn.o'. */
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+ "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+
+/* This is for -profile to use -lc_p instead of -lc. */
+#undef CC1_SPEC
+#define CC1_SPEC "%{profile:-p} \
+%{sun4:} %{target:} \
+%{mcypress:-mcpu=cypress} \
+%{msparclite:-mcpu=sparclite} %{mf930:-mcpu=f930} %{mf934:-mcpu=f934} \
+%{mv8:-mcpu=v8} %{msupersparc:-mcpu=supersparc} \
+"
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (sparc GNU/Linux with ELF)");
+
+#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 -Dsparc -Dlinux -Asystem(unix) -Asystem(posix)"
+
+#undef CPP_SUBTARGET_SPEC
+#ifdef USE_GNULIBC_1
+#define CPP_SUBTARGET_SPEC \
+"%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}"
+#else
+#define CPP_SUBTARGET_SPEC \
+"%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}"
+#endif
+
+#undef LIB_SPEC
+/* We no longer link with libc_p.a or libg.a by default. If you
+ want to profile or debug the GNU/Linux C library, please add
+ -lc_p or -ggdb to LDFLAGS at the link time, respectively. */
+#if 1
+#ifdef USE_GNULIBC_1
+#define LIB_SPEC \
+ "%{!shared: %{p:-lgmon} %{pg:-lgmon} %{profile:-lgmon -lc_p} \
+ %{!profile:%{!ggdb:-lc} %{ggdb:-lg}}}"
+#else
+#define LIB_SPEC \
+ "%{!shared: %{mieee-fp:-lieee} %{pthread:-lpthread} \
+ %{profile:-lc_p} %{!profile: -lc}}"
+#endif
+#else
+#define LIB_SPEC \
+ "%{!shared: \
+ %{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} \
+ %{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}}"
+#endif
+
+/* Provide a LINK_SPEC appropriate for GNU/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 elf32_sparc -Y P,/usr/lib %{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 elf32_sparc -Y P,/usr/lib %{shared:-shared} \
+ %{!shared: \
+ %{!ibcs: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.1}} \
+ %{static:-static}}}"
+#endif
+#else
+#define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \
+ %{!shared: \
+ %{!ibcs: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \
+ %{static:-static}}}"
+#endif
+
+/* The sun bundled assembler doesn't accept -Yd, (and neither does gas).
+ It's safe to pass -s always, even if -g is not used. */
+#undef ASM_SPEC
+#define ASM_SPEC \
+ "%{V} %{v:%{!V:-V}} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s %{fpic:-K PIC} %{fPIC:-K PIC}"
+
+/* Same as sparc.h */
+#undef DBX_REGISTER_NUMBER
+#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+
+/* We use stabs-in-elf for debugging, because that is what the native
+ toolchain uses. XXX */
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+#undef ASM_OUTPUT_ALIGNED_LOCAL
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
+do { \
+ fputs ("\t.local\t", (FILE)); \
+ assemble_name ((FILE), (NAME)); \
+ putc ('\n', (FILE)); \
+ ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \
+} while (0)
+
+#undef COMMON_ASM_OP
+#define COMMON_ASM_OP "\t.common"
+
+/* This is how to output a definition of 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, ".L%s%d:\n", PREFIX, NUM)
+
+/* This is how to output a reference to an internal numbered label where
+ PREFIX is the class of label and NUM is the number within the class. */
+
+#undef ASM_OUTPUT_INTERNAL_LABELREF
+#define ASM_OUTPUT_INTERNAL_LABELREF(FILE,PREFIX,NUM) \
+ fprintf (FILE, ".L%s%d", PREFIX, NUM)
+
+/* This is how to store into the string LABEL
+ 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(LABEL,PREFIX,NUM) \
+ sprintf (LABEL, "*.L%s%d", PREFIX, NUM)
+
+
+#if 0
+/* Define for support of TFmode long double and REAL_ARITHMETIC.
+ Sparc ABI says that long double is 4 words. GNU/Linux does not support
+ long double yet. */
+#define LONG_DOUBLE_TYPE_SIZE 128
+#endif
diff --git a/gnu/usr.bin/gcc/config/sparc/linux64.h b/gnu/usr.bin/gcc/config/sparc/linux64.h
new file mode 100644
index 00000000000..74f632bb48c
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/linux64.h
@@ -0,0 +1,236 @@
+/* Definitions for 64-bit SPARC running Linux-based GNU systems with ELF.
+ Copyright 1996, 1997 Free Software Foundation, Inc.
+ Contributed by David S. Miller (davem@caip.rutgers.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. */
+
+/* ??? bi-architecture support will require changes to the linker
+ related specs, among perhaps other things (multilibs). */
+/* #define SPARC_BI_ARCH */
+
+#define LINUX_DEFAULT_ELF
+
+/* Don't assume anything about the header files. */
+#define NO_IMPLICIT_EXTERN_C
+
+#undef HAVE_ATEXIT
+#define HAVE_ATEXIT
+
+#include <sparc/sysv4.h>
+
+#undef MD_EXEC_PREFIX
+#undef MD_STARTFILE_PREFIX
+
+/* 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)
+
+#undef ASM_CPU_DEFAULT_SPEC
+#define ASM_CPU_DEFAULT_SPEC "-Av9a"
+
+#undef LIBGCC_SPEC
+#define LIBGCC_SPEC \
+ "%{!shared:-lgcc}"
+
+/* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add
+ the GNU/Linux magical crtbegin.o file (see crtstuff.c) which
+ provides part of the support for getting C++ file-scope static
+ object constructed before entering `main'. */
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+ "%{!shared: \
+ %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
+ crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+
+/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
+ the GNU/Linux magical crtend.o file (see crtstuff.c) which
+ provides part of the support for getting C++ file-scope static
+ object constructed before entering `main', followed by a normal
+ GNU/Linux "finalizer" file, `crtn.o'. */
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+ "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (sparc64 GNU/Linux with ELF)");
+
+/* A 64 bit v9 compiler with stack-bias,
+ in a Medium/Anywhere code model environment. */
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT \
+ (MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ \
+ + MASK_STACK_BIAS + MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU)
+
+/* The default code model. */
+#undef SPARC_DEFAULT_CMODEL
+#define SPARC_DEFAULT_CMODEL CM_MEDANY
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "long long unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "long long int"
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "long int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+#undef LONG_DOUBLE_TYPE_SIZE
+#define LONG_DOUBLE_TYPE_SIZE 128
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-D__ELF__ -Dunix -Dsparc -Dlinux -Asystem(unix) -Asystem(posix)"
+
+#undef CPP_SUBTARGET_SPEC
+#define CPP_SUBTARGET_SPEC "\
+%{fPIC:-D__PIC__ -D__pic__} \
+%{fpic:-D__PIC__ -D__pic__} \
+%{posix:-D_POSIX_SOURCE} \
+"
+/* We no longer link with libc_p.a or libg.a by default. If you
+ want to profile or debug the GNU/Linux C library, please add
+ -lc_p or -ggdb to LDFLAGS at the link time, respectively. */
+#undef LIB_SPEC
+#define LIB_SPEC \
+ "%{!shared: %{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} \
+ %{!ggdb:-lc} %{ggdb:-lg}}"
+
+/* Provide a LINK_SPEC appropriate for GNU/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
+#define LINK_SPEC "-m elf64_sparc -Y P,/usr/lib %{shared:-shared} \
+ %{!shared: \
+ %{!ibcs: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld-linux64.so.2}} \
+ %{static:-static}}} \
+%{mlittle-endian:-EL} \
+"
+
+/* The sun bundled assembler doesn't accept -Yd, (and neither does gas).
+ It's safe to pass -s always, even if -g is not used. */
+#undef ASM_SPEC
+#define ASM_SPEC "\
+%{V} \
+%{v:%{!V:-V}} \
+%{!Qn:-Qy} \
+%{n} \
+%{T} \
+%{Ym,*} \
+%{Wa,*:%*} \
+-s %{fpic:-K PIC} %{fPIC:-K PIC} \
+%{mlittle-endian:-EL} \
+%(asm_cpu) %(asm_arch) \
+"
+
+/* Same as sparc.h */
+#undef DBX_REGISTER_NUMBER
+#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+
+/* System V Release 4 uses DWARF debugging info. Buf DWARF1 doesn't do
+ 64-bit anything, so we use DWARF2. */
+
+#undef DWARF2_DEBUGGING_INFO
+#undef DWARF_DEBUGGING_INFO
+#undef DBX_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO
+
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+
+#undef ASM_OUTPUT_ALIGNED_LOCAL
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
+do { \
+ fputs ("\t.local\t", (FILE)); \
+ assemble_name ((FILE), (NAME)); \
+ putc ('\n', (FILE)); \
+ ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \
+} while (0)
+
+#undef COMMON_ASM_OP
+#define COMMON_ASM_OP "\t.common"
+
+/* This is how to output a definition of 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, ".L%s%d:\n", PREFIX, NUM)
+
+/* This is how to output a reference to an internal numbered label where
+ PREFIX is the class of label and NUM is the number within the class. */
+
+#undef ASM_OUTPUT_INTERNAL_LABELREF
+#define ASM_OUTPUT_INTERNAL_LABELREF(FILE,PREFIX,NUM) \
+ fprintf (FILE, ".L%s%d", PREFIX, NUM)
+
+/* This is how to store into the string LABEL
+ 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(LABEL,PREFIX,NUM) \
+ sprintf (LABEL, "*.L%s%d", PREFIX, NUM)
+
+/* Stabs doesn't use this, and it confuses a simulator. */
+/* ??? Need to see what DWARF needs, if anything. */
+#undef ASM_IDENTIFY_GCC
+#define ASM_IDENTIFY_GCC(FILE)
+
+/* Define the names of various pseudo-ops used by the Sparc/svr4 assembler.
+ ??? If ints are 64 bits then UNALIGNED_INT_ASM_OP (defined elsewhere) is
+ misnamed. These should all refer to explicit sizes (half/word/xword?),
+ anything other than short/int/long/etc. */
+
+#define UNALIGNED_DOUBLE_INT_ASM_OP ".uaxword"
+
+/* DWARF bits. */
+
+/* Follow Irix 6 and not the Dwarf2 draft in using 64-bit offsets.
+ Obviously the Dwarf2 folks havn't tried to actually build systems
+ with their spec. On a 64-bit system, only 64-bit relocs become
+ RELATIVE relocations. */
+
+/* #define DWARF_OFFSET_SIZE PTR_SIZE */
diff --git a/gnu/usr.bin/gcc/config/sparc/rtems.h b/gnu/usr.bin/gcc/config/sparc/rtems.h
new file mode 100644
index 00000000000..55b7779818a
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/rtems.h
@@ -0,0 +1,28 @@
+/* Definitions for rtems targeting a SPARC using a.out.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Joel Sherrill (joel@OARcorp.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 "sparc/aout.h"
+
+/* Specify predefined symbols in preprocessor. */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Dsparc -D__GCC_NEW_VARARGS__ -Drtems -D__rtems__ \
+ -Asystem(rtems) -Acpu(sparc) -Amachine(sparc)"
diff --git a/gnu/usr.bin/gcc/config/sparc/sol2-g1.asm b/gnu/usr.bin/gcc/config/sparc/sol2-g1.asm
new file mode 100644
index 00000000000..b9d878856f8
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/sol2-g1.asm
@@ -0,0 +1,88 @@
+! gcrt1.s for solaris 2.0.
+
+! Copyright (C) 1992 Free Software Foundation, Inc.
+! Written By David Vinayak Henkel-Wallace, June 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 SVr4 ABI.
+! This file is the first thing linked into any executable.
+
+ .section ".text"
+ .proc 022
+ .global _start
+
+_start:
+ mov 0, %fp ! Mark bottom frame pointer
+ ld [%sp + 64], %l0 ! argc
+ add %sp, 68, %l1 ! argv
+
+ ! Leave some room for a call. Sun leaves 32 octets (to sit on
+ ! a cache line?) so we do too.
+ sub %sp, 32, %sp
+
+ ! %g1 may contain a function to be registered w/atexit
+ orcc %g0, %g1, %g0
+ be .nope
+ mov %g1, %o0
+ call atexit
+ nop
+.nope:
+ ! Now make sure constructors and destructors are handled.
+ set _fini, %o0
+ call atexit, 1
+ nop
+ call _init, 0
+ nop
+
+ ! We ignore the auxiliary vector; there's no defined way to
+ ! access those data anyway. Instead, go straight to main:
+ mov %l0, %o0 ! argc
+ mov %l1, %o1 ! argv
+ set ___Argv, %o3
+ st %o1, [%o3] ! *___Argv
+ ! Skip argc words past argv, to env:
+ sll %l0, 2, %o2
+ add %o2, 4, %o2
+ add %l1, %o2, %o2 ! env
+ set _environ, %o3
+ st %o2, [%o3] ! *_environ
+ call main, 4
+ nop
+ call exit, 0
+ nop
+ call _exit, 0
+ nop
+ ! We should never get here.
+
+ .type _start,#function
+ .size _start,.-_start
diff --git a/gnu/usr.bin/gcc/config/sparc/splet.h b/gnu/usr.bin/gcc/config/sparc/splet.h
new file mode 100644
index 00000000000..23c6414417a
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/splet.h
@@ -0,0 +1,53 @@
+/* Definitions of target machine for GNU compiler, for SPARClet.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Doug Evans (dje@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 "sparc/aout.h"
+
+/* -mbroken-saverestore is not included here because the long term
+ default is -mno-broken-saverestore. */
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_APP_REGS + MASK_EPILOGUE)
+
+/* -mlive-g0 is only supported on the sparclet. */
+#undef SUBTARGET_SWITCHES
+#define SUBTARGET_SWITCHES \
+{"big-endian", -MASK_LITTLE_ENDIAN}, \
+{"little-endian", MASK_LITTLE_ENDIAN}, \
+{"live-g0", MASK_LIVE_G0}, \
+{"no-live-g0", -MASK_LIVE_G0}, \
+{"broken-saverestore", MASK_BROKEN_SAVERESTORE}, \
+{"no-broken-saverestore", -MASK_BROKEN_SAVERESTORE},
+
+#undef ASM_SPEC
+#define ASM_SPEC "%{mlittle-endian:-EL} %(asm_cpu)"
+
+/* Require the user to supply crt0.o. */
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC ""
+
+#undef LINK_SPEC
+#define LINK_SPEC "%{mlittle-endian:-EL}"
+
+/* sparclet chips are bi-endian. */
+#undef BYTES_BIG_ENDIAN
+#define BYTES_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN)
+#undef WORDS_BIG_ENDIAN
+#define WORDS_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN)
diff --git a/gnu/usr.bin/gcc/config/sparc/sun4gas.h b/gnu/usr.bin/gcc/config/sparc/sun4gas.h
new file mode 100644
index 00000000000..3cea9560b4f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/sun4gas.h
@@ -0,0 +1,27 @@
+/* Definitions of target machine for GNU compiler, for SunOS 4.x with gas
+ Copyright (C) 1997 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. */
+
+/* gas supports unaligned data. */
+#define UNALIGNED_DOUBLE_INT_ASM_OP ".uaxword"
+#define UNALIGNED_INT_ASM_OP ".uaword"
+#define UNALIGNED_SHORT_ASM_OP ".uahalf"
+
+/* defaults.h will define DWARF2_UNWIND_INFO for us. */
+#undef DWARF2_UNWIND_INFO
diff --git a/gnu/usr.bin/gcc/config/sparc/t-elf b/gnu/usr.bin/gcc/config/sparc/t-elf
new file mode 100644
index 00000000000..da9df38368e
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/t-elf
@@ -0,0 +1,39 @@
+# we need to supply our own assembly versions of libgcc1.c files,
+# since the user may not have native 'cc' available
+
+CROSS_LIBGCC1 = libgcc1-asm.a
+LIB1ASMSRC = sparc/lb1spc.asm
+LIB1ASMFUNCS = _mulsi3 _divsi3 _modsi3
+
+# crt0 is built elsewhere
+LIBGCC1_TEST =
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so...
+
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+# MULTILIB_OPTIONS should have msparclite too, but we'd have to make
+# gas build...
+#MULTILIB_OPTIONS = msoft-float mcpu=v8
+MULTILIB_OPTIONS = msoft-float
+#MULTILIB_DIRNAMES = soft v8
+MULTILIB_DIRNAMES = soft
+#MULTILIB_MATCHES = msoft-float=mno-fpu mcpu?v8=mv8
+MULTILIB_MATCHES = msoft-float=mno-fpu
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+
+# Assemble startup files.
+crti.o: $(srcdir)/config/sparc/sol2-ci.asm $(GCC_PASSES)
+ $(GCC_FOR_TARGET) -c -o crti.o -x assembler $(srcdir)/config/sparc/sol2-ci.asm
+crtn.o: $(srcdir)/config/sparc/sol2-cn.asm $(GCC_PASSES)
+ $(GCC_FOR_TARGET) -c -o crtn.o -x assembler $(srcdir)/config/sparc/sol2-cn.asm
diff --git a/gnu/usr.bin/gcc/config/sparc/t-linux b/gnu/usr.bin/gcc/config/sparc/t-linux
new file mode 100644
index 00000000000..6e37a023005
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/t-linux
@@ -0,0 +1,6 @@
+LIBGCC1 =
+CROSS_LIBGCC1 =
+
+# We don't want to build .umul, etc., because gnu/Linux provides them,
+# which means that libgcc1-test will fail for cross-compiler.
+LIBGCC1_TEST =
diff --git a/gnu/usr.bin/gcc/config/sparc/t-splet b/gnu/usr.bin/gcc/config/sparc/t-splet
new file mode 100644
index 00000000000..3409f5dfe88
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/t-splet
@@ -0,0 +1,23 @@
+# configuration file for a bare sparclet cpu, aout format files
+
+CROSS_LIBGCC1 = libgcc1-asm.a
+LIB1ASMSRC = sparc/lb1spc.asm
+LIB1ASMFUNCS = _mulsi3 _divsi3 _modsi3
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so...
+
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+MULTILIB_OPTIONS = mlittle-endian mlive-g0 mbroken-saverestore
+MULTILIB_DIRNAMES = little live-g0 brknsave
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
diff --git a/gnu/usr.bin/gcc/config/sparc/vxsim.h b/gnu/usr.bin/gcc/config/sparc/vxsim.h
new file mode 100644
index 00000000000..6c80375f56b
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/vxsim.h
@@ -0,0 +1,131 @@
+/* Definitions of target machine for GNU compiler, for SPARC VxSim
+ Copyright 1996 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. */
+
+/* Supposedly the same as vanilla sparc svr4, except for the stuff below: */
+#include "sparc/sysv4.h"
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES \
+ "-DCPU=SIMSPARCSOLARIS -D__vxworks -D__vxworks__ -Dsparc -D__svr4__ -D__SVR4 \
+ -Asystem(embedded) -Asystem(svr4) -Acpu(sparc) -Amachine(sparc)\
+ -D__GCC_NEW_VARARGS__"
+
+#undef CPP_SPEC
+#define CPP_SPEC ""
+
+#undef CC1_SPEC
+#define CC1_SPEC "-fno-builtin %{sun4:} %{target:}"
+
+/* The sun bundled assembler doesn't accept -Yd, (and neither does gas).
+ It's safe to pass -s always, even if -g is not used. */
+#undef ASM_SPEC
+#define ASM_SPEC \
+ "%{V} %{v:%{!V:-V}} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s \
+ %{fpic:-K PIC} %{fPIC:-K PIC}"
+
+/* However it appears that Solaris 2.0 uses the same reg numbering as
+ the old BSD-style system did. */
+
+#undef DBX_REGISTER_NUMBER
+/* Same as sparc.h */
+#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+
+/* We use stabs-in-elf for debugging, because that is what the native
+ toolchain uses. */
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+/* The Solaris 2 assembler uses .skip, not .zero, so put this back. */
+#undef ASM_OUTPUT_SKIP
+#define ASM_OUTPUT_SKIP(FILE,SIZE) \
+ fprintf (FILE, "\t.skip %u\n", (SIZE))
+
+#undef ASM_OUTPUT_ALIGNED_LOCAL
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
+do { \
+ fputs ("\t.local\t", (FILE)); \
+ assemble_name ((FILE), (NAME)); \
+ putc ('\n', (FILE)); \
+ ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \
+} while (0)
+
+#undef COMMON_ASM_OP
+#define COMMON_ASM_OP "\t.common"
+
+/* This is how to output a definition of 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, ".L%s%d:\n", PREFIX, NUM)
+
+/* This is how to output a reference to an internal numbered label where
+ PREFIX is the class of label and NUM is the number within the class. */
+
+#undef ASM_OUTPUT_INTERNAL_LABELREF
+#define ASM_OUTPUT_INTERNAL_LABELREF(FILE,PREFIX,NUM) \
+ fprintf (FILE, ".L%s%d", PREFIX, NUM)
+
+/* This is how to store into the string LABEL
+ 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(LABEL,PREFIX,NUM) \
+ sprintf (LABEL, "*.L%s%d", PREFIX, NUM)
+
+
+
+#undef LIB_SPEC
+#define LIB_SPEC ""
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC ""
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC ""
+
+#undef LINK_SPEC
+#define LINK_SPEC "-r"
+
+/* 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')
+
+/* ??? This does not work in SunOS 4.x, so it is not enabled in sparc.h.
+ Instead, it is enabled here, because it does work under Solaris. */
+/* Define for support of TFmode long double and REAL_ARITHMETIC.
+ Sparc ABI says that long double is 4 words. */
+#define LONG_DOUBLE_TYPE_SIZE 64
diff --git a/gnu/usr.bin/gcc/config/sparc/xm-linux.h b/gnu/usr.bin/gcc/config/sparc/xm-linux.h
new file mode 100644
index 00000000000..f68f5715662
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/xm-linux.h
@@ -0,0 +1,28 @@
+/* Configuration for GCC for SPARC running Linux-based GNU systems.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Eddie C. Dost (ecd@skynet.be)
+
+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 inhibit_libc
+#include <alloca.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include <xm-linux.h>
diff --git a/gnu/usr.bin/gcc/config/sparc/xm-sp64.h b/gnu/usr.bin/gcc/config/sparc/xm-sp64.h
new file mode 100644
index 00000000000..5954affa3b5
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/sparc/xm-sp64.h
@@ -0,0 +1,25 @@
+/* Configuration for GCC for Sparc v9 running 64-bit native.
+ Copyright (C) 1997 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 <sparc/xm-sparc.h>
+
+/* This describes the machine the compiler is hosted on. */
+#undef HOST_BITS_PER_LONG
+#define HOST_BITS_PER_LONG 64
diff --git a/gnu/usr.bin/gcc/config/t-gnu b/gnu/usr.bin/gcc/config/t-gnu
new file mode 100644
index 00000000000..58969f21e20
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/t-gnu
@@ -0,0 +1,13 @@
+LIBGCC1=libgcc1.null
+CROSS_LIBGCC1=libgcc1.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
+TARGET_LIBGCC2_CFLAGS = -fPIC
diff --git a/gnu/usr.bin/gcc/config/t-linux b/gnu/usr.bin/gcc/config/t-linux
new file mode 100644
index 00000000000..843fa1bdf79
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/t-linux
@@ -0,0 +1,10 @@
+# Don't run fixproto
+STMP_FIXPROTO =
+
+# Don't install "assert.h" in gcc. We use the one in glibc.
+INSTALL_ASSERT_H =
+
+# Compile crtbeginS.o and crtendS.o with pic.
+CRTSTUFF_T_CFLAGS_S = -fPIC
+# Compile libgcc2.a with pic.
+TARGET_LIBGCC2_CFLAGS = -fPIC
diff --git a/gnu/usr.bin/gcc/config/t-linux-aout b/gnu/usr.bin/gcc/config/t-linux-aout
new file mode 100644
index 00000000000..a7c091799e8
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/t-linux-aout
@@ -0,0 +1,5 @@
+# Don't run fixproto
+STMP_FIXPROTO =
+
+# Don't install "assert.h" in gcc. We use the one in glibc.
+INSTALL_ASSERT_H =
diff --git a/gnu/usr.bin/gcc/config/t-linux-gnulibc1 b/gnu/usr.bin/gcc/config/t-linux-gnulibc1
new file mode 100644
index 00000000000..7bb7bce85b3
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/t-linux-gnulibc1
@@ -0,0 +1,2 @@
+# We are building for the Linux C library 5.
+T_CFLAGS = -DUSE_GNULIBC_1
diff --git a/gnu/usr.bin/gcc/config/t-netbsd b/gnu/usr.bin/gcc/config/t-netbsd
new file mode 100644
index 00000000000..a3d9e22eaf0
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/t-netbsd
@@ -0,0 +1,8 @@
+LIBGCC1=libgcc1.null
+CROSS_LIBGCC1=libgcc1.null
+
+# Don't run fixproto
+STMP_FIXPROTO =
+
+# Don't install "assert.h" in gcc. We use the one in glibc.
+INSTALL_ASSERT_H =
diff --git a/gnu/usr.bin/gcc/config/t-rtems b/gnu/usr.bin/gcc/config/t-rtems
new file mode 100644
index 00000000000..25dd398dd52
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/t-rtems
@@ -0,0 +1,2 @@
+# RTEMS uses newlib which does not require prototype fixing
+STMP_FIXPROTO =
diff --git a/gnu/usr.bin/gcc/config/v850/lib1funcs.asm b/gnu/usr.bin/gcc/config/v850/lib1funcs.asm
new file mode 100644
index 00000000000..b140c4385e1
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/v850/lib1funcs.asm
@@ -0,0 +1,1269 @@
+/* libgcc1 routines for NEC V850.
+ Copyright (C) 1996, 1997 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.
+
+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. */
+
+#ifdef L_mulsi3
+ .text
+ .globl ___mulsi3
+ .type ___mulsi3,@function
+
+/*
+ * In order to not deal with negative numbers (mulh is a signed multiply
+ * and we want an unsigned multiply, code the multiplication as a series
+ * of 7 bit multiplies).
+ *
+ * int __mulsi3 (unsigned a, unsigned b)
+ * {
+ * int i, j;
+ * int ret = 0;
+ *
+ * for (i = 0; i < 32; i += 7)
+ * {
+ * short a_part = a & 0x7f;
+ * unsigned b_tmp = b;
+ * a >>= 7;
+ *
+ * for (j = 0; (i+j) < 32; j += 7)
+ * {
+ * short b_part = b_tmp & 0x7f;
+ * ret += (((int)a_part) * ((int)b_part)) << (i+j);
+ * b_tmp >>= 7;
+ * }
+ * }
+ *
+ * return ret;
+ * }
+ */
+
+___mulsi3:
+ mov 0,r10 /* total */
+ mov 0,r14 /* i = 0, index for multiply a's part */
+ movea lo(31),r0,r16 /* upper bounds for loop */
+.L5:
+ mov r7,r13 /* b_tmp = b */
+ andi 0x7f,r6,r15 /* a_part = (a & 127) */
+ shr 7,r6 /* a >>= 7 */
+ mov r14,r12 /* i+j = i */
+.L9:
+ andi 0x7f,r13,r11 /* b_part = (b_tmp & 127) */
+ mulh r15,r11 /* ((int)a_part) * ((int)b_part) */
+ shr 7,r13 /* b_tmp >>= 7 */
+ shl r12,r11 /* (((int)a_part) * ((int)b_part)) << (i+j) */
+ add r11,r10 /* ret += (((int)a_part) * ((int)b_part)) << (i+j) */
+ add 7,r12 /* i+j += 7 */
+ cmp r16,r12 /* i+j < 32 */
+ ble .L9
+
+ add 7,r14 /* i += 7 */
+ cmp r16,r14 /* i < 32 */
+ ble .L5
+
+ jmp [r31] /* return */
+ .size __mulsi3,.-__mulsi3
+#endif
+
+#ifdef L_udivsi3
+ .global ___udivsi3
+___udivsi3:
+ mov 1,r12
+ mov 0,r10
+ cmp r6,r7
+ bnl .L12
+ movhi hi(-2147483648),r0,r13
+ cmp r0,r7
+ blt .L12
+.L4:
+ shl 1,r7
+ shl 1,r12
+ cmp r6,r7
+ bnl .L12
+ cmp r0,r12
+ be .L8
+ mov r7,r5
+ and r13,r5
+ be .L4
+ br .L12
+.L9:
+ cmp r7,r6
+ bl .L10
+ sub r7,r6
+ or r12,r10
+.L10:
+ shr 1,r12
+ shr 1,r7
+.L12:
+ cmp r0,r12
+ bne .L9
+.L8:
+ jmp [r31]
+ .size __udivsi3,.-__udivsi3
+#endif
+
+#ifdef L_divsi3
+ .text
+ .globl ___divsi3
+ .type ___divsi3,@function
+___divsi3:
+ add -8,sp
+ st.w r31,4[sp]
+ st.w r22,0[sp]
+ mov 1,r22
+ tst r7,r7
+ bp .L3
+ subr r0,r7
+ subr r0,r22
+.L3:
+ tst r6,r6
+ bp .L4
+ subr r0,r6
+ subr r0,r22
+.L4:
+ jarl ___udivsi3,r31
+ cmp r0,r22
+ bp .L7
+ subr r0,r10
+.L7:
+ ld.w 0[sp],r22
+ ld.w 4[sp],r31
+ add 8,sp
+ jmp [r31]
+ .size __divsi3,.-__divsi3
+#endif
+
+#ifdef L_umodsi3
+ .text
+ .globl ___umodsi3
+ .type ___umodsi3,@function
+___umodsi3:
+ add -12,sp
+ st.w r31,8[sp]
+ st.w r7,4[sp]
+ st.w r6,0[sp]
+ jarl ___udivsi3,r31
+ ld.w 4[sp],r7
+ mov r10,r6
+ jarl ___mulsi3,r31
+ ld.w 0[sp],r6
+ subr r6,r10
+ ld.w 8[sp],r31
+ add 12,sp
+ jmp [r31]
+ .size __umodsi3,.-__umodsi3
+#endif /* L_umodsi3 */
+
+#ifdef L_modsi3
+ .text
+ .globl ___modsi3
+ .type ___modsi3,@function
+___modsi3:
+ add -12,sp
+ st.w r31,8[sp]
+ st.w r7,4[sp]
+ st.w r6,0[sp]
+ jarl ___divsi3,r31
+ ld.w 4[sp],r7
+ mov r10,r6
+ jarl ___mulsi3,r31
+ ld.w 0[sp],r6
+ subr r6,r10
+ ld.w 8[sp],r31
+ add 12,sp
+ jmp [r31]
+ .size __modsi3,.-__modsi3
+#endif /* L_modsi3 */
+
+#ifdef L_save_2
+ .text
+ .align 2
+ .globl __save_r2_r29
+ .type __save_r2_r29,@function
+ /* Allocate space and save registers 2, 20 .. 29 on the stack */
+ /* Called via: jalr __save_r2_r29,r10 */
+__save_r2_r29:
+ mov ep,r1
+ addi -44,sp,sp
+ mov sp,ep
+ sst.w r29,0[ep]
+ sst.w r28,4[ep]
+ sst.w r27,8[ep]
+ sst.w r26,12[ep]
+ sst.w r25,16[ep]
+ sst.w r24,20[ep]
+ sst.w r23,24[ep]
+ sst.w r22,28[ep]
+ sst.w r21,32[ep]
+ sst.w r20,36[ep]
+ sst.w r2,40[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r2_r29,.-__save_r2_r29
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r2_r29 */
+ .align 2
+ .globl __return_r2_r29
+ .type __return_r2_r29,@function
+__return_r2_r29:
+ mov ep,r1
+ mov sp,ep
+ sld.w 0[ep],r29
+ sld.w 4[ep],r28
+ sld.w 8[ep],r27
+ sld.w 12[ep],r26
+ sld.w 16[ep],r25
+ sld.w 20[ep],r24
+ sld.w 24[ep],r23
+ sld.w 28[ep],r22
+ sld.w 32[ep],r21
+ sld.w 36[ep],r20
+ sld.w 40[ep],r2
+ addi 44,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r2_r29,.-__return_r2_r29
+#endif /* L_save_2 */
+
+#ifdef L_save_20
+ .text
+ .align 2
+ .globl __save_r20_r29
+ .type __save_r20_r29,@function
+ /* Allocate space and save registers 20 .. 29 on the stack */
+ /* Called via: jalr __save_r20_r29,r10 */
+__save_r20_r29:
+ mov ep,r1
+ addi -40,sp,sp
+ mov sp,ep
+ sst.w r29,0[ep]
+ sst.w r28,4[ep]
+ sst.w r27,8[ep]
+ sst.w r26,12[ep]
+ sst.w r25,16[ep]
+ sst.w r24,20[ep]
+ sst.w r23,24[ep]
+ sst.w r22,28[ep]
+ sst.w r21,32[ep]
+ sst.w r20,36[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r20_r29,.-__save_r20_r29
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r20_r29 */
+ .align 2
+ .globl __return_r20_r29
+ .type __return_r20_r29,@function
+__return_r20_r29:
+ mov ep,r1
+ mov sp,ep
+ sld.w 0[ep],r29
+ sld.w 4[ep],r28
+ sld.w 8[ep],r27
+ sld.w 12[ep],r26
+ sld.w 16[ep],r25
+ sld.w 20[ep],r24
+ sld.w 24[ep],r23
+ sld.w 28[ep],r22
+ sld.w 32[ep],r21
+ sld.w 36[ep],r20
+ addi 40,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r20_r29,.-__return_r20_r29
+#endif /* L_save_20 */
+
+#ifdef L_save_21
+ .text
+ .align 2
+ .globl __save_r21_r29
+ .type __save_r21_r29,@function
+ /* Allocate space and save registers 21 .. 29 on the stack */
+ /* Called via: jalr __save_r21_r29,r10 */
+__save_r21_r29:
+ mov ep,r1
+ addi -36,sp,sp
+ mov sp,ep
+ sst.w r29,0[ep]
+ sst.w r28,4[ep]
+ sst.w r27,8[ep]
+ sst.w r26,12[ep]
+ sst.w r25,16[ep]
+ sst.w r24,20[ep]
+ sst.w r23,24[ep]
+ sst.w r22,28[ep]
+ sst.w r21,32[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r21_r29,.-__save_r21_r29
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r21_r29 */
+ .align 2
+ .globl __return_r21_r29
+ .type __return_r21_r29,@function
+__return_r21_r29:
+ mov ep,r1
+ mov sp,ep
+ sld.w 0[ep],r29
+ sld.w 4[ep],r28
+ sld.w 8[ep],r27
+ sld.w 12[ep],r26
+ sld.w 16[ep],r25
+ sld.w 20[ep],r24
+ sld.w 24[ep],r23
+ sld.w 28[ep],r22
+ sld.w 32[ep],r21
+ addi 36,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r21_r29,.-__return_r21_r29
+#endif /* L_save_21 */
+
+#ifdef L_save_22
+ .text
+ .align 2
+ .globl __save_r22_r29
+ .type __save_r22_r29,@function
+ /* Allocate space and save registers 22 .. 29 on the stack */
+ /* Called via: jalr __save_r22_r29,r10 */
+__save_r22_r29:
+ mov ep,r1
+ addi -32,sp,sp
+ mov sp,ep
+ sst.w r29,0[ep]
+ sst.w r28,4[ep]
+ sst.w r27,8[ep]
+ sst.w r26,12[ep]
+ sst.w r25,16[ep]
+ sst.w r24,20[ep]
+ sst.w r23,24[ep]
+ sst.w r22,28[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r22_r29,.-__save_r22_r29
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r22_r29 */
+ .align 2
+ .globl __return_r22_r29
+ .type __return_r22_r29,@function
+__return_r22_r29:
+ mov ep,r1
+ mov sp,ep
+ sld.w 0[ep],r29
+ sld.w 4[ep],r28
+ sld.w 8[ep],r27
+ sld.w 12[ep],r26
+ sld.w 16[ep],r25
+ sld.w 20[ep],r24
+ sld.w 24[ep],r23
+ sld.w 28[ep],r22
+ addi 32,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r22_r29,.-__return_r22_r29
+#endif /* L_save_22 */
+
+#ifdef L_save_23
+ .text
+ .align 2
+ .globl __save_r23_r29
+ .type __save_r23_r29,@function
+ /* Allocate space and save registers 23 .. 29 on the stack */
+ /* Called via: jalr __save_r23_r29,r10 */
+__save_r23_r29:
+ mov ep,r1
+ addi -28,sp,sp
+ mov sp,ep
+ sst.w r29,0[ep]
+ sst.w r28,4[ep]
+ sst.w r27,8[ep]
+ sst.w r26,12[ep]
+ sst.w r25,16[ep]
+ sst.w r24,20[ep]
+ sst.w r23,24[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r23_r29,.-__save_r23_r29
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r23_r29 */
+ .align 2
+ .globl __return_r23_r29
+ .type __return_r23_r29,@function
+__return_r23_r29:
+ mov ep,r1
+ mov sp,ep
+ sld.w 0[ep],r29
+ sld.w 4[ep],r28
+ sld.w 8[ep],r27
+ sld.w 12[ep],r26
+ sld.w 16[ep],r25
+ sld.w 20[ep],r24
+ sld.w 24[ep],r23
+ addi 28,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r23_r29,.-__return_r23_r29
+#endif /* L_save_23 */
+
+#ifdef L_save_24
+ .text
+ .align 2
+ .globl __save_r24_r29
+ .type __save_r24_r29,@function
+ /* Allocate space and save registers 24 .. 29 on the stack */
+ /* Called via: jalr __save_r24_r29,r10 */
+__save_r24_r29:
+ mov ep,r1
+ addi -24,sp,sp
+ mov sp,ep
+ sst.w r29,0[ep]
+ sst.w r28,4[ep]
+ sst.w r27,8[ep]
+ sst.w r26,12[ep]
+ sst.w r25,16[ep]
+ sst.w r24,20[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r24_r29,.-__save_r24_r29
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r24_r29 */
+ .align 2
+ .globl __return_r24_r29
+ .type __return_r24_r29,@function
+__return_r24_r29:
+ mov ep,r1
+ mov sp,ep
+ sld.w 0[ep],r29
+ sld.w 4[ep],r28
+ sld.w 8[ep],r27
+ sld.w 12[ep],r26
+ sld.w 16[ep],r25
+ sld.w 20[ep],r24
+ addi 24,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r24_r29,.-__return_r24_r29
+#endif /* L_save_24 */
+
+#ifdef L_save_25
+ .text
+ .align 2
+ .globl __save_r25_r29
+ .type __save_r25_r29,@function
+ /* Allocate space and save registers 25 .. 29 on the stack */
+ /* Called via: jalr __save_r25_r29,r10 */
+__save_r25_r29:
+ mov ep,r1
+ addi -20,sp,sp
+ mov sp,ep
+ sst.w r29,0[ep]
+ sst.w r28,4[ep]
+ sst.w r27,8[ep]
+ sst.w r26,12[ep]
+ sst.w r25,16[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r25_r29,.-__save_r25_r29
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r25_r29 */
+ .align 2
+ .globl __return_r25_r29
+ .type __return_r25_r29,@function
+__return_r25_r29:
+ mov ep,r1
+ mov sp,ep
+ sld.w 0[ep],r29
+ sld.w 4[ep],r28
+ sld.w 8[ep],r27
+ sld.w 12[ep],r26
+ sld.w 16[ep],r25
+ addi 20,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r25_r29,.-__return_r25_r29
+#endif /* L_save_25 */
+
+#ifdef L_save_26
+ .text
+ .align 2
+ .globl __save_r26_r29
+ .type __save_r26_r29,@function
+ /* Allocate space and save registers 26 .. 29 on the stack */
+ /* Called via: jalr __save_r26_r29,r10 */
+__save_r26_r29:
+ mov ep,r1
+ add -16,sp
+ mov sp,ep
+ sst.w r29,0[ep]
+ sst.w r28,4[ep]
+ sst.w r27,8[ep]
+ sst.w r26,12[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r26_r29,.-__save_r26_r29
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r26_r29 */
+ .align 2
+ .globl __return_r26_r29
+ .type __return_r26_r29,@function
+__return_r26_r29:
+ mov ep,r1
+ mov sp,ep
+ sld.w 0[ep],r29
+ sld.w 4[ep],r28
+ sld.w 8[ep],r27
+ sld.w 12[ep],r26
+ addi 16,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r26_r29,.-__return_r26_r29
+#endif /* L_save_26 */
+
+#ifdef L_save_27
+ .text
+ .align 2
+ .globl __save_r27_r29
+ .type __save_r27_r29,@function
+ /* Allocate space and save registers 27 .. 29 on the stack */
+ /* Called via: jalr __save_r27_r29,r10 */
+__save_r27_r29:
+ add -12,sp
+ st.w r29,0[sp]
+ st.w r28,4[sp]
+ st.w r27,8[sp]
+ jmp [r10]
+ .size __save_r27_r29,.-__save_r27_r29
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r27_r29 */
+ .align 2
+ .globl __return_r27_r29
+ .type __return_r27_r29,@function
+__return_r27_r29:
+ ld.w 0[sp],r29
+ ld.w 4[sp],r28
+ ld.w 8[sp],r27
+ add 12,sp
+ jmp [r31]
+ .size __return_r27_r29,.-__return_r27_r29
+#endif /* L_save_27 */
+
+#ifdef L_save_28
+ .text
+ .align 2
+ .globl __save_r28_r29
+ .type __save_r28_r29,@function
+ /* Allocate space and save registers 28,29 on the stack */
+ /* Called via: jalr __save_r28_r29,r10 */
+__save_r28_r29:
+ add -8,sp
+ st.w r29,0[sp]
+ st.w r28,4[sp]
+ jmp [r10]
+ .size __save_r28_r29,.-__save_r28_r29
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r28_r29 */
+ .align 2
+ .globl __return_r28_r29
+ .type __return_r28_r29,@function
+__return_r28_r29:
+ ld.w 0[sp],r29
+ ld.w 4[sp],r28
+ add 8,sp
+ jmp [r31]
+ .size __return_r28_r29,.-__return_r28_r29
+#endif /* L_save_28 */
+
+#ifdef L_save_29
+ .text
+ .align 2
+ .globl __save_r29
+ .type __save_r29,@function
+ /* Allocate space and save register 29 on the stack */
+ /* Called via: jalr __save_r29,r10 */
+__save_r29:
+ add -4,sp
+ st.w r29,0[sp]
+ jmp [r10]
+ .size __save_r29,.-__save_r29
+
+ /* Restore saved register 29, deallocate stack and return to the user */
+ /* Called via: jr __return_r29 */
+ .align 2
+ .globl __return_r29
+ .type __return_r29,@function
+__return_r29:
+ ld.w 0[sp],r29
+ add 4,sp
+ jmp [r31]
+ .size __return_r29,.-__return_r29
+#endif /* L_save_28 */
+
+#ifdef L_save_2c
+ .text
+ .align 2
+ .globl __save_r2_r31
+ .type __save_r2_r31,@function
+ /* Allocate space and save registers 20 .. 29, 31 on the stack */
+ /* Also allocate space for the argument save area */
+ /* Called via: jalr __save_r2_r31,r10 */
+__save_r2_r31:
+ mov ep,r1
+ addi -64,sp,sp
+ mov sp,ep
+ sst.w r29,16[ep]
+ sst.w r28,20[ep]
+ sst.w r27,24[ep]
+ sst.w r26,28[ep]
+ sst.w r25,32[ep]
+ sst.w r24,36[ep]
+ sst.w r23,40[ep]
+ sst.w r22,44[ep]
+ sst.w r21,48[ep]
+ sst.w r20,52[ep]
+ sst.w r2,56[ep]
+ sst.w r31,60[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r2_r31,.-__save_r2_r31
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r20_r31 */
+ .align 2
+ .globl __return_r2_r31
+ .type __return_r2_r31,@function
+__return_r2_r31:
+ mov ep,r1
+ mov sp,ep
+ sld.w 16[ep],r29
+ sld.w 20[ep],r28
+ sld.w 24[ep],r27
+ sld.w 28[ep],r26
+ sld.w 32[ep],r25
+ sld.w 36[ep],r24
+ sld.w 40[ep],r23
+ sld.w 44[ep],r22
+ sld.w 48[ep],r21
+ sld.w 52[ep],r20
+ sld.w 56[ep],r2
+ sld.w 60[ep],r31
+ addi 64,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r2_r31,.-__return_r2_r31
+#endif /* L_save_2c */
+
+#ifdef L_save_20c
+ .text
+ .align 2
+ .globl __save_r20_r31
+ .type __save_r20_r31,@function
+ /* Allocate space and save registers 20 .. 29, 31 on the stack */
+ /* Also allocate space for the argument save area */
+ /* Called via: jalr __save_r20_r31,r10 */
+__save_r20_r31:
+ mov ep,r1
+ addi -60,sp,sp
+ mov sp,ep
+ sst.w r29,16[ep]
+ sst.w r28,20[ep]
+ sst.w r27,24[ep]
+ sst.w r26,28[ep]
+ sst.w r25,32[ep]
+ sst.w r24,36[ep]
+ sst.w r23,40[ep]
+ sst.w r22,44[ep]
+ sst.w r21,48[ep]
+ sst.w r20,52[ep]
+ sst.w r31,56[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r20_r31,.-__save_r20_r31
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r20_r31 */
+ .align 2
+ .globl __return_r20_r31
+ .type __return_r20_r31,@function
+__return_r20_r31:
+ mov ep,r1
+ mov sp,ep
+ sld.w 16[ep],r29
+ sld.w 20[ep],r28
+ sld.w 24[ep],r27
+ sld.w 28[ep],r26
+ sld.w 32[ep],r25
+ sld.w 36[ep],r24
+ sld.w 40[ep],r23
+ sld.w 44[ep],r22
+ sld.w 48[ep],r21
+ sld.w 52[ep],r20
+ sld.w 56[ep],r31
+ addi 60,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r20_r31,.-__return_r20_r31
+#endif /* L_save_20c */
+
+#ifdef L_save_21c
+ .text
+ .align 2
+ .globl __save_r21_r31
+ .type __save_r21_r31,@function
+ /* Allocate space and save registers 21 .. 29, 31 on the stack */
+ /* Also allocate space for the argument save area */
+ /* Called via: jalr __save_r21_r31,r10 */
+__save_r21_r31:
+ mov ep,r1
+ addi -56,sp,sp
+ mov sp,ep
+ sst.w r29,16[ep]
+ sst.w r28,20[ep]
+ sst.w r27,24[ep]
+ sst.w r26,28[ep]
+ sst.w r25,32[ep]
+ sst.w r24,36[ep]
+ sst.w r23,40[ep]
+ sst.w r22,44[ep]
+ sst.w r21,48[ep]
+ sst.w r31,52[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r21_r31,.-__save_r21_r31
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r21_r31 */
+ .align 2
+ .globl __return_r21_r31
+ .type __return_r21_r31,@function
+__return_r21_r31:
+ mov ep,r1
+ mov sp,ep
+ sld.w 16[ep],r29
+ sld.w 20[ep],r28
+ sld.w 24[ep],r27
+ sld.w 28[ep],r26
+ sld.w 32[ep],r25
+ sld.w 36[ep],r24
+ sld.w 40[ep],r23
+ sld.w 44[ep],r22
+ sld.w 48[ep],r21
+ sld.w 52[ep],r31
+ addi 56,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r21_r31,.-__return_r21_r31
+#endif /* L_save_21c */
+
+#ifdef L_save_22c
+ .text
+ .align 2
+ .globl __save_r22_r31
+ .type __save_r22_r31,@function
+ /* Allocate space and save registers 22 .. 29, 31 on the stack */
+ /* Also allocate space for the argument save area */
+ /* Called via: jalr __save_r22_r31,r10 */
+__save_r22_r31:
+ mov ep,r1
+ addi -52,sp,sp
+ mov sp,ep
+ sst.w r29,16[ep]
+ sst.w r28,20[ep]
+ sst.w r27,24[ep]
+ sst.w r26,28[ep]
+ sst.w r25,32[ep]
+ sst.w r24,36[ep]
+ sst.w r23,40[ep]
+ sst.w r22,44[ep]
+ sst.w r31,48[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r22_r31,.-__save_r22_r31
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r22_r31 */
+ .align 2
+ .globl __return_r22_r31
+ .type __return_r22_r31,@function
+__return_r22_r31:
+ mov ep,r1
+ mov sp,ep
+ sld.w 16[ep],r29
+ sld.w 20[ep],r28
+ sld.w 24[ep],r27
+ sld.w 28[ep],r26
+ sld.w 32[ep],r25
+ sld.w 36[ep],r24
+ sld.w 40[ep],r23
+ sld.w 44[ep],r22
+ sld.w 48[ep],r31
+ addi 52,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r22_r31,.-__return_r22_r31
+#endif /* L_save_22c */
+
+#ifdef L_save_23c
+ .text
+ .align 2
+ .globl __save_r23_r31
+ .type __save_r23_r31,@function
+ /* Allocate space and save registers 23 .. 29, 31 on the stack */
+ /* Also allocate space for the argument save area */
+ /* Called via: jalr __save_r23_r31,r10 */
+__save_r23_r31:
+ mov ep,r1
+ addi -48,sp,sp
+ mov sp,ep
+ sst.w r29,16[ep]
+ sst.w r28,20[ep]
+ sst.w r27,24[ep]
+ sst.w r26,28[ep]
+ sst.w r25,32[ep]
+ sst.w r24,36[ep]
+ sst.w r23,40[ep]
+ sst.w r31,44[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r23_r31,.-__save_r23_r31
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r23_r31 */
+ .align 2
+ .globl __return_r23_r31
+ .type __return_r23_r31,@function
+__return_r23_r31:
+ mov ep,r1
+ mov sp,ep
+ sld.w 16[ep],r29
+ sld.w 20[ep],r28
+ sld.w 24[ep],r27
+ sld.w 28[ep],r26
+ sld.w 32[ep],r25
+ sld.w 36[ep],r24
+ sld.w 40[ep],r23
+ sld.w 44[ep],r31
+ addi 48,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r23_r31,.-__return_r23_r31
+#endif /* L_save_23c */
+
+#ifdef L_save_24c
+ .text
+ .align 2
+ .globl __save_r24_r31
+ .type __save_r24_r31,@function
+ /* Allocate space and save registers 24 .. 29, 31 on the stack */
+ /* Also allocate space for the argument save area */
+ /* Called via: jalr __save_r24_r31,r10 */
+__save_r24_r31:
+ mov ep,r1
+ addi -44,sp,sp
+ mov sp,ep
+ sst.w r29,16[ep]
+ sst.w r28,20[ep]
+ sst.w r27,24[ep]
+ sst.w r26,28[ep]
+ sst.w r25,32[ep]
+ sst.w r24,36[ep]
+ sst.w r31,40[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r24_r31,.-__save_r24_r31
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r24_r31 */
+ .align 2
+ .globl __return_r24_r31
+ .type __return_r24_r31,@function
+__return_r24_r31:
+ mov ep,r1
+ mov sp,ep
+ sld.w 16[ep],r29
+ sld.w 20[ep],r28
+ sld.w 24[ep],r27
+ sld.w 28[ep],r26
+ sld.w 32[ep],r25
+ sld.w 36[ep],r24
+ sld.w 40[ep],r31
+ addi 44,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r24_r31,.-__return_r24_r31
+#endif /* L_save_24c */
+
+#ifdef L_save_25c
+ .text
+ .align 2
+ .globl __save_r25_r31
+ .type __save_r25_r31,@function
+ /* Allocate space and save registers 25 .. 29, 31 on the stack */
+ /* Also allocate space for the argument save area */
+ /* Called via: jalr __save_r25_r31,r10 */
+__save_r25_r31:
+ mov ep,r1
+ addi -40,sp,sp
+ mov sp,ep
+ sst.w r29,16[ep]
+ sst.w r28,20[ep]
+ sst.w r27,24[ep]
+ sst.w r26,28[ep]
+ sst.w r25,32[ep]
+ sst.w r31,36[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r25_r31,.-__save_r25_r31
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r25_r31 */
+ .align 2
+ .globl __return_r25_r31
+ .type __return_r25_r31,@function
+__return_r25_r31:
+ mov ep,r1
+ mov sp,ep
+ sld.w 16[ep],r29
+ sld.w 20[ep],r28
+ sld.w 24[ep],r27
+ sld.w 28[ep],r26
+ sld.w 32[ep],r25
+ sld.w 36[ep],r31
+ addi 40,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r25_r31,.-__return_r25_r31
+#endif /* L_save_25c */
+
+#ifdef L_save_26c
+ .text
+ .align 2
+ .globl __save_r26_r31
+ .type __save_r26_r31,@function
+ /* Allocate space and save registers 26 .. 29, 31 on the stack */
+ /* Also allocate space for the argument save area */
+ /* Called via: jalr __save_r26_r31,r10 */
+__save_r26_r31:
+ mov ep,r1
+ addi -36,sp,sp
+ mov sp,ep
+ sst.w r29,16[ep]
+ sst.w r28,20[ep]
+ sst.w r27,24[ep]
+ sst.w r26,28[ep]
+ sst.w r31,32[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r26_r31,.-__save_r26_r31
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r26_r31 */
+ .align 2
+ .globl __return_r26_r31
+ .type __return_r26_r31,@function
+__return_r26_r31:
+ mov ep,r1
+ mov sp,ep
+ sld.w 16[ep],r29
+ sld.w 20[ep],r28
+ sld.w 24[ep],r27
+ sld.w 28[ep],r26
+ sld.w 32[ep],r31
+ addi 36,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r26_r31,.-__return_r26_r31
+#endif /* L_save_26c */
+
+#ifdef L_save_27c
+ .text
+ .align 2
+ .globl __save_r27_r31
+ .type __save_r27_r31,@function
+ /* Allocate space and save registers 27 .. 29, 31 on the stack */
+ /* Also allocate space for the argument save area */
+ /* Called via: jalr __save_r27_r31,r10 */
+__save_r27_r31:
+ mov ep,r1
+ addi -32,sp,sp
+ mov sp,ep
+ sst.w r29,16[ep]
+ sst.w r28,20[ep]
+ sst.w r27,24[ep]
+ sst.w r31,28[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r27_r31,.-__save_r27_r31
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r27_r31 */
+ .align 2
+ .globl __return_r27_r31
+ .type __return_r27_r31,@function
+__return_r27_r31:
+ mov ep,r1
+ mov sp,ep
+ sld.w 16[ep],r29
+ sld.w 20[ep],r28
+ sld.w 24[ep],r27
+ sld.w 28[ep],r31
+ addi 32,sp,sp
+ mov r1,ep
+ jmp [r31]
+ .size __return_r27_r31,.-__return_r27_r31
+#endif /* L_save_27c */
+
+#ifdef L_save_28c
+ .text
+ .align 2
+ .globl __save_r28_r31
+ .type __save_r28_r31,@function
+ /* Allocate space and save registers 28 .. 29, 31 on the stack */
+ /* Also allocate space for the argument save area */
+ /* Called via: jalr __save_r28_r31,r10 */
+__save_r28_r31:
+ addi -28,sp,sp
+ st.w r29,16[sp]
+ st.w r28,20[sp]
+ st.w r31,24[sp]
+ jmp [r10]
+ .size __save_r28_r31,.-__save_r28_r31
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r28_r31 */
+ .align 2
+ .globl __return_r28_r31
+ .type __return_r28_r31,@function
+__return_r28_r31:
+ ld.w 16[sp],r29
+ ld.w 20[sp],r28
+ ld.w 24[sp],r31
+ addi 28,sp,sp
+ jmp [r31]
+ .size __return_r28_r31,.-__return_r28_r31
+#endif /* L_save_28c */
+
+#ifdef L_save_29c
+ .text
+ .align 2
+ .globl __save_r29_r31
+ .type __save_r29_r31,@function
+ /* Allocate space and save registers 29 & 31 on the stack */
+ /* Also allocate space for the argument save area */
+ /* Called via: jalr __save_r29_r31,r10 */
+__save_r29_r31:
+ addi -24,sp,sp
+ st.w r29,16[sp]
+ st.w r31,20[sp]
+ jmp [r10]
+ .size __save_r29_r31,.-__save_r29_r31
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r29_r31 */
+ .align 2
+ .globl __return_r29_r31
+ .type __return_r29_r31,@function
+__return_r29_r31:
+ ld.w 16[sp],r29
+ ld.w 20[sp],r31
+ addi 24,sp,sp
+ jmp [r31]
+ .size __return_r29_r31,.-__return_r29_r31
+#endif /* L_save_29c */
+
+#ifdef L_save_31c
+ .text
+ .align 2
+ .globl __save_r31
+ .type __save_r31,@function
+ /* Allocate space and save register 31 on the stack */
+ /* Also allocate space for the argument save area */
+ /* Called via: jalr __save_r29_r31,r10 */
+__save_r31:
+ addi -20,sp,sp
+ st.w r31,16[sp]
+ jmp [r10]
+ .size __save_r31,.-__save_r31
+
+ /* Restore saved registers, deallocate stack and return to the user */
+ /* Called via: jr __return_r31 */
+ .align 2
+ .globl __return_r31
+ .type __return_r31,@function
+__return_r31:
+ ld.w 16[sp],r31
+ addi 20,sp,sp
+ jmp [r31]
+ .size __return_r29_r31,.-__return_r29_r31
+#endif /* L_save_31c */
+
+#ifdef L_save_varargs
+ .text
+ .align 2
+ .globl __save_r6_r9
+ .type __save_r6_r9,@function
+ /* Save registers 6 .. 9 on the stack for variable argument functions */
+ /* Called via: jalr __save_r6_r9,r10 */
+__save_r6_r9:
+ mov ep,r1
+ mov sp,ep
+ sst.w r6,0[ep]
+ sst.w r7,4[ep]
+ sst.w r8,8[ep]
+ sst.w r9,12[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_r6_r9,.-__save_r6_r9
+#endif /* L_save_varargs */
+
+#ifdef L_save_interrupt
+ .text
+ .align 2
+ .globl __save_interrupt
+ .type __save_interrupt,@function
+ /* Save registers r1, r4 on stack and load up with expected values */
+ /* Note, 12 bytes of stack have already been allocated. */
+ /* Called via: jalr __save_interrupt,r10 */
+__save_interrupt:
+ st.w ep,0[sp]
+ st.w gp,4[sp]
+ st.w r1,8[sp]
+ movhi hi(__ep),r0,ep
+ movea lo(__ep),ep,ep
+ movhi hi(__gp),r0,gp
+ movea lo(__gp),gp,gp
+ jmp [r10]
+ .size __save_interrupt,.-__save_interrupt
+
+ /* Restore saved registers, deallocate stack and return from the interrupt */
+ /* Called via: jr __return_interrupt */
+ .align 2
+ .globl __return_interrupt
+ .type __return_interrupt,@function
+__return_interrupt:
+ ld.w 0[sp],ep
+ ld.w 4[sp],gp
+ ld.w 8[sp],r1
+ ld.w 12[sp],r10
+ add 16,sp
+ reti
+ .size __return_interrupt,.-__return_interrupt
+#endif /* L_save_interrupt */
+
+#ifdef L_save_all_interrupt
+ .text
+ .align 2
+ .globl __save_all_interrupt
+ .type __save_all_interrupt,@function
+ /* Save all registers except for those saved in __save_interrupt */
+ /* allocate enough stack for all of the registers & 16 bytes of space */
+ /* Called via: jalr __save_all_interrupt,r10 */
+__save_all_interrupt:
+ addi -120,sp,sp
+ mov ep,r1
+ mov sp,ep
+ sst.w r31,116[ep]
+ sst.w r2,112[ep]
+ sst.w gp,108[ep]
+ sst.w r6,104[ep]
+ sst.w r7,100[ep]
+ sst.w r8,96[ep]
+ sst.w r9,92[ep]
+ sst.w r11,88[ep]
+ sst.w r12,84[ep]
+ sst.w r13,80[ep]
+ sst.w r14,76[ep]
+ sst.w r15,72[ep]
+ sst.w r16,68[ep]
+ sst.w r17,64[ep]
+ sst.w r18,60[ep]
+ sst.w r19,56[ep]
+ sst.w r20,52[ep]
+ sst.w r21,48[ep]
+ sst.w r22,44[ep]
+ sst.w r23,40[ep]
+ sst.w r24,36[ep]
+ sst.w r25,32[ep]
+ sst.w r26,28[ep]
+ sst.w r27,24[ep]
+ sst.w r28,20[ep]
+ sst.w r29,16[ep]
+ mov r1,ep
+ jmp [r10]
+ .size __save_all_interrupt,.-__save_all_interrupt
+
+ .globl __restore_all_interrupt
+ .type __restore_all_interrupt,@function
+ /* Restore all registers saved in __save_all_interrupt */
+ /* & deallocate the stack space */
+ /* Called via: jalr __restore_all_interrupt,r10 */
+__restore_all_interrupt:
+ mov ep,r1
+ mov sp,ep
+ sld.w 116[ep],r31
+ sld.w 112[ep],r2
+ sld.w 108[ep],gp
+ sld.w 104[ep],r6
+ sld.w 100[ep],r7
+ sld.w 96[ep],r8
+ sld.w 92[ep],r9
+ sld.w 88[ep],r11
+ sld.w 84[ep],r12
+ sld.w 80[ep],r13
+ sld.w 76[ep],r14
+ sld.w 72[ep],r15
+ sld.w 68[ep],r16
+ sld.w 64[ep],r17
+ sld.w 60[ep],r18
+ sld.w 56[ep],r19
+ sld.w 52[ep],r20
+ sld.w 48[ep],r21
+ sld.w 44[ep],r22
+ sld.w 40[ep],r23
+ sld.w 36[ep],r24
+ sld.w 32[ep],r25
+ sld.w 28[ep],r26
+ sld.w 24[ep],r27
+ sld.w 20[ep],r28
+ sld.w 16[ep],r29
+ mov r1,ep
+ addi 120,sp,sp
+ jmp [r10]
+ .size __restore_all_interrupt,.-__restore_all_interrupt
+#endif /* L_save_all_interrupt */
diff --git a/gnu/usr.bin/gcc/config/v850/t-v850 b/gnu/usr.bin/gcc/config/v850/t-v850
new file mode 100644
index 00000000000..d1d9b16f1b6
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/v850/t-v850
@@ -0,0 +1,52 @@
+CROSS_LIBGCC1 = libgcc1-asm.a
+LIB1ASMSRC = v850/lib1funcs.asm
+LIB1ASMFUNCS = _mulsi3 \
+ _divsi3 \
+ _udivsi3 \
+ _modsi3 \
+ _umodsi3 \
+ _save_2 \
+ _save_20 \
+ _save_21 \
+ _save_22 \
+ _save_23 \
+ _save_24 \
+ _save_25 \
+ _save_26 \
+ _save_27 \
+ _save_28 \
+ _save_29 \
+ _save_2c \
+ _save_20c \
+ _save_21c \
+ _save_22c \
+ _save_23c \
+ _save_24c \
+ _save_25c \
+ _save_26c \
+ _save_27c \
+ _save_28c \
+ _save_29c \
+ _save_31c \
+ _save_varargs \
+ _save_interrupt \
+ _save_all_interrupt
+
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so...
+
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#ifdef __LITTLE_ENDIAN__' > dp-bit.c
+ echo '#define FLOAT_BIT_ORDER_MISMATCH' >>dp-bit.c
+ echo '#endif' >> dp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ echo '#ifdef __LITTLE_ENDIAN__' >> fp-bit.c
+ echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c
+ echo '#endif' >> fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
diff --git a/gnu/usr.bin/gcc/config/v850/v850.c b/gnu/usr.bin/gcc/config/v850/v850.c
new file mode 100644
index 00000000000..8f5c768bbe2
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/v850/v850.c
@@ -0,0 +1,2284 @@
+/* Subroutines for insn-output.c for NEC V850 series
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Jeff Law (law@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 <stdio.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 "flags.h"
+#include "recog.h"
+#include "expr.h"
+#include "tree.h"
+#include "obstack.h"
+
+/* True if the current function has anonymous arguments. */
+int current_function_anonymous_args;
+
+/* Information about the various small memory areas. */
+struct small_memory_info small_memory[ (int)SMALL_MEMORY_max ] =
+{
+ /* name value max physical max */
+ { "tda", (char *)0, 0, 256 },
+ { "sda", (char *)0, 0, 65536 },
+ { "zda", (char *)0, 0, 32768 },
+};
+
+/* True if we don't need to check any more if the current
+ function is an interrupt handler */
+static int v850_interrupt_cache_p = FALSE;
+
+/* Whether current function is an interrupt handler. */
+static int v850_interrupt_p = FALSE;
+
+
+/* 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 i;
+ extern int atoi ();
+
+ /* Parse -m{s,t,z}da=nnn switches */
+ for (i = 0; i < (int)SMALL_MEMORY_max; i++)
+ {
+ if (small_memory[i].value)
+ {
+ if (!isdigit (*small_memory[i].value))
+ error ("%s=%s is not numeric.",
+ small_memory[i].name,
+ small_memory[i].value);
+ else
+ {
+ small_memory[i].max = atoi (small_memory[i].value);
+ if (small_memory[i].max > small_memory[i].physical_max)
+ error ("%s=%s is too large.",
+ small_memory[i].name,
+ small_memory[i].value);
+ }
+ }
+ }
+}
+
+
+/* Output assembly code for the start of the file. */
+
+void
+asm_file_start (file)
+ FILE *file;
+{
+ output_file_directive (file, main_input_filename);
+}
+
+
+/* Return an RTX to represent where a value with mode MODE will be returned
+ from a function. If the result is 0, the argument is pushed. */
+
+rtx
+function_arg (cum, mode, type, named)
+ CUMULATIVE_ARGS *cum;
+ enum machine_mode mode;
+ tree type;
+ int named;
+{
+ rtx result = 0;
+ int size, align;
+
+ if (TARGET_GHS && !named)
+ return NULL_RTX;
+
+ if (mode == BLKmode)
+ size = int_size_in_bytes (type);
+ else
+ size = GET_MODE_SIZE (mode);
+
+ if (type)
+ align = TYPE_ALIGN (type) / BITS_PER_UNIT;
+ else
+ align = size;
+
+ cum->nbytes = (cum->nbytes + align - 1) &~(align - 1);
+
+ if (cum->nbytes > 4 * UNITS_PER_WORD)
+ return 0;
+
+ if (type == NULL_TREE
+ && cum->nbytes + size > 4 * UNITS_PER_WORD)
+ return 0;
+
+ switch (cum->nbytes / UNITS_PER_WORD)
+ {
+ case 0:
+ result = gen_rtx (REG, mode, 6);
+ break;
+ case 1:
+ result = gen_rtx (REG, mode, 7);
+ break;
+ case 2:
+ result = gen_rtx (REG, mode, 8);
+ break;
+ case 3:
+ result = gen_rtx (REG, mode, 9);
+ break;
+ default:
+ result = 0;
+ }
+
+ return result;
+}
+
+
+/* Return the number of words which must be put into registers
+ for values which are part in registers and part in memory. */
+
+int
+function_arg_partial_nregs (cum, mode, type, named)
+ CUMULATIVE_ARGS *cum;
+ enum machine_mode mode;
+ tree type;
+ int named;
+{
+ int size, align;
+
+ if (TARGET_GHS && !named)
+ return 0;
+
+ if (mode == BLKmode)
+ size = int_size_in_bytes (type);
+ else
+ size = GET_MODE_SIZE (mode);
+
+ if (type)
+ align = TYPE_ALIGN (type) / BITS_PER_UNIT;
+ else
+ align = size;
+
+ cum->nbytes = (cum->nbytes + align - 1) &~(align - 1);
+
+ if (cum->nbytes > 4 * UNITS_PER_WORD)
+ return 0;
+
+ if (cum->nbytes + size <= 4 * UNITS_PER_WORD)
+ return 0;
+
+ if (type == NULL_TREE
+ && cum->nbytes + size > 4 * UNITS_PER_WORD)
+ return 0;
+
+ return (4 * UNITS_PER_WORD - cum->nbytes) / UNITS_PER_WORD;
+}
+
+
+/* Return the high and low words of a CONST_DOUBLE */
+
+static void
+const_double_split (x, p_high, p_low)
+ rtx x;
+ HOST_WIDE_INT *p_high;
+ HOST_WIDE_INT *p_low;
+{
+ if (GET_CODE (x) == CONST_DOUBLE)
+ {
+ long t[2];
+ REAL_VALUE_TYPE rv;
+
+ switch (GET_MODE (x))
+ {
+ case DFmode:
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+ REAL_VALUE_TO_TARGET_DOUBLE (rv, t);
+ *p_high = t[1]; /* since v850 is little endian */
+ *p_low = t[0]; /* high is second word */
+ return;
+
+ case SFmode:
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+ REAL_VALUE_TO_TARGET_SINGLE (rv, *p_high);
+ *p_low = 0;
+ return;
+
+ case VOIDmode:
+ case DImode:
+ *p_high = CONST_DOUBLE_HIGH (x);
+ *p_low = CONST_DOUBLE_LOW (x);
+ return;
+ }
+ }
+
+ fatal_insn ("const_double_split got a bad insn:", x);
+}
+
+
+/* Return the cost of the rtx R with code CODE. */
+
+static int
+const_costs_int (value, zero_cost)
+ HOST_WIDE_INT value;
+ int zero_cost;
+{
+ if (CONST_OK_FOR_I (value))
+ return zero_cost;
+ else if (CONST_OK_FOR_J (value))
+ return 1;
+ else if (CONST_OK_FOR_K (value))
+ return 2;
+ else
+ return 4;
+}
+
+int
+const_costs (r, c)
+ rtx r;
+ enum rtx_code c;
+{
+ HOST_WIDE_INT high, low;
+
+ switch (c)
+ {
+ case CONST_INT:
+ return const_costs_int (INTVAL (r), 0);
+
+ case CONST_DOUBLE:
+ const_double_split (r, &high, &low);
+ if (GET_MODE (r) == SFmode)
+ return const_costs_int (high, 1);
+ else
+ return const_costs_int (high, 1) + const_costs_int (low, 1);
+
+ case SYMBOL_REF:
+ case LABEL_REF:
+ case CONST:
+ return 2;
+
+ case HIGH:
+ return 1;
+
+ default:
+ return 4;
+ }
+}
+
+
+/* Print operand X using operand code CODE to assembly language output file
+ FILE. */
+
+void
+print_operand (file, x, code)
+ FILE *file;
+ rtx x;
+ int code;
+{
+ HOST_WIDE_INT high, low;
+
+ switch (code)
+ {
+ case 'b':
+ case 'B':
+ case 'c':
+ case 'C':
+ switch ((code == 'B' || code == 'C')
+ ? reverse_condition (GET_CODE (x)) : GET_CODE (x))
+ {
+ case NE:
+ if (code == 'c' || code == 'C')
+ fprintf (file, "nz");
+ else
+ fprintf (file, "ne");
+ break;
+ case EQ:
+ if (code == 'c' || code == 'C')
+ fprintf (file, "z");
+ else
+ fprintf (file, "e");
+ break;
+ case GE:
+ fprintf (file, "ge");
+ break;
+ case GT:
+ fprintf (file, "gt");
+ break;
+ case LE:
+ fprintf (file, "le");
+ break;
+ case LT:
+ fprintf (file, "lt");
+ break;
+ case GEU:
+ fprintf (file, "nl");
+ break;
+ case GTU:
+ fprintf (file, "h");
+ break;
+ case LEU:
+ fprintf (file, "nh");
+ break;
+ case LTU:
+ fprintf (file, "l");
+ break;
+ default:
+ abort ();
+ }
+ break;
+ case 'F': /* high word of CONST_DOUBLE */
+ if (GET_CODE (x) == CONST_INT)
+ fprintf (file, "%d", (INTVAL (x) >= 0) ? 0 : -1);
+ else if (GET_CODE (x) == CONST_DOUBLE)
+ {
+ const_double_split (x, &high, &low);
+ fprintf (file, "%ld", (long) high);
+ }
+ else
+ abort ();
+ break;
+ case 'G': /* low word of CONST_DOUBLE */
+ if (GET_CODE (x) == CONST_INT)
+ fprintf (file, "%ld", (long) INTVAL (x));
+ else if (GET_CODE (x) == CONST_DOUBLE)
+ {
+ const_double_split (x, &high, &low);
+ fprintf (file, "%ld", (long) low);
+ }
+ else
+ abort ();
+ break;
+ case 'L':
+ fprintf (file, "%d\n", INTVAL (x) & 0xffff);
+ break;
+ case 'M':
+ fprintf (file, "%d", exact_log2 (INTVAL (x)));
+ break;
+ case 'O':
+ if (special_symbolref_operand (x, VOIDmode))
+ {
+ char* name;
+
+ if (GET_CODE (x) == SYMBOL_REF)
+ name = XSTR (x, 0);
+ else if (GET_CODE (x) == CONST)
+ name = XSTR (XEXP (XEXP (x, 0), 0), 0);
+ else
+ abort ();
+
+ if (ZDA_NAME_P (name))
+ fprintf (file, "zdaoff");
+ else if (SDA_NAME_P (name))
+ fprintf (file, "sdaoff");
+ else if (TDA_NAME_P (name))
+ fprintf (file, "tdaoff");
+ else
+ abort();
+ }
+ else
+ abort();
+ break;
+ case 'P':
+ if (special_symbolref_operand (x, VOIDmode))
+ output_addr_const (file, x);
+ else
+ abort();
+ break;
+ case 'Q':
+ if (special_symbolref_operand (x, VOIDmode))
+ {
+ char* name;
+
+ if (GET_CODE (x) == SYMBOL_REF)
+ name = XSTR (x, 0);
+ else if (GET_CODE (x) == CONST)
+ name = XSTR (XEXP (XEXP (x, 0), 0), 0);
+ else
+ abort ();
+
+ if (ZDA_NAME_P (name))
+ fprintf (file, "r0");
+ else if (SDA_NAME_P (name))
+ fprintf (file, "gp");
+ else if (TDA_NAME_P (name))
+ fprintf (file, "ep");
+ else
+ abort();
+ }
+ else
+ abort();
+ break;
+ case 'R': /* 2nd word of a double. */
+ switch (GET_CODE (x))
+ {
+ case REG:
+ fprintf (file, reg_names[REGNO (x) + 1]);
+ break;
+ case MEM:
+ print_operand_address (file,
+ XEXP (adj_offsettable_operand (x, 4), 0));
+ break;
+ }
+ break;
+ case 'S':
+ {
+ /* if it's a reference to a TDA variable, use sst/sld vs. st/ld */
+ if (GET_CODE (x) == MEM && ep_memory_operand (x, GET_MODE (x), FALSE))
+ fputs ("s", file);
+
+ break;
+ }
+ case 'T':
+ {
+ /* Like an 'S' operand above, but for unsigned loads only. */
+ if (GET_CODE (x) == MEM && ep_memory_operand (x, GET_MODE (x), TRUE))
+ fputs ("s", file);
+
+ break;
+ }
+ case 'W': /* print the instruction suffix */
+ switch (GET_MODE (x))
+ {
+ default:
+ abort ();
+
+ case QImode: fputs (".b", file); break;
+ case HImode: fputs (".h", file); break;
+ case SImode: fputs (".w", file); break;
+ case SFmode: fputs (".w", file); break;
+ }
+ break;
+ case '.': /* register r0 */
+ fputs (reg_names[0], file);
+ break;
+ case 'z': /* reg or zero */
+ if (x == const0_rtx)
+ fputs (reg_names[0], file);
+ else if (GET_CODE (x) == REG)
+ fputs (reg_names[REGNO (x)], file);
+ else
+ abort ();
+ break;
+ default:
+ switch (GET_CODE (x))
+ {
+ case MEM:
+ if (GET_CODE (XEXP (x, 0)) == CONST_INT)
+ output_address (gen_rtx (PLUS, SImode,
+ gen_rtx (REG, SImode, 0),
+ XEXP (x, 0)));
+ else
+ output_address (XEXP (x, 0));
+ break;
+
+ case REG:
+ fputs (reg_names[REGNO (x)], file);
+ break;
+ case SUBREG:
+ fputs (reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)], file);
+ break;
+ case CONST_INT:
+ case SYMBOL_REF:
+ case CONST:
+ case LABEL_REF:
+ case CODE_LABEL:
+ print_operand_address (file, x);
+ break;
+ default:
+ abort ();
+ }
+ break;
+
+ }
+}
+
+
+/* Output assembly language output for the address ADDR to FILE. */
+
+void
+print_operand_address (file, addr)
+ FILE *file;
+ rtx addr;
+{
+ switch (GET_CODE (addr))
+ {
+ case REG:
+ fprintf (file, "0[");
+ print_operand (file, addr, 0);
+ fprintf (file, "]");
+ break;
+ case LO_SUM:
+ if (GET_CODE (XEXP (addr, 0)) == REG)
+ {
+ /* reg,foo */
+ fprintf (file, "lo(");
+ print_operand (file, XEXP (addr, 1), 0);
+ fprintf (file, ")[");
+ print_operand (file, XEXP (addr, 0), 0);
+ fprintf (file, "]");
+ }
+ break;
+ case PLUS:
+ if (GET_CODE (XEXP (addr, 0)) == REG
+ || GET_CODE (XEXP (addr, 0)) == SUBREG)
+ {
+ /* reg,foo */
+ print_operand (file, XEXP (addr, 1), 0);
+ fprintf (file, "[");
+ print_operand (file, XEXP (addr, 0), 0);
+ fprintf (file, "]");
+ }
+ else
+ {
+ print_operand (file, XEXP (addr, 0), 0);
+ fprintf (file, "+");
+ print_operand (file, XEXP (addr, 1), 0);
+ }
+ break;
+ case SYMBOL_REF:
+ if (ENCODED_NAME_P (XSTR (addr, 0)))
+ {
+ char* name = XSTR (addr, 0);
+ char* off_name;
+ char* reg_name;
+
+ if (ZDA_NAME_P (name))
+ {
+ off_name = "zdaoff";
+ reg_name = "r0";
+ }
+ else if (SDA_NAME_P (name))
+ {
+ off_name = "sdaoff";
+ reg_name = "gp";
+ }
+ else if (TDA_NAME_P (name))
+ {
+ off_name = "tdaoff";
+ reg_name = "ep";
+ }
+ else
+ abort();
+
+ fprintf (file, "%s(", off_name);
+ output_addr_const (file, addr);
+ fprintf (file, ")[%s]", reg_name);
+ }
+ else
+ output_addr_const (file, addr);
+ break;
+ case CONST:
+ if (special_symbolref_operand (addr, VOIDmode))
+ {
+ char* name = XSTR (XEXP (XEXP (addr, 0), 0), 0);
+ char* off_name;
+ char* reg_name;
+
+ if (ZDA_NAME_P (name))
+ {
+ off_name = "zdaoff";
+ reg_name = "r0";
+ }
+ else if (SDA_NAME_P (name))
+ {
+ off_name = "sdaoff";
+ reg_name = "gp";
+ }
+ else if (TDA_NAME_P (name))
+ {
+ off_name = "tdaoff";
+ reg_name = "ep";
+ }
+ else
+ abort();
+
+ fprintf (file, "%s(", off_name);
+ output_addr_const (file, addr);
+ fprintf (file, ")[%s]", reg_name);
+ }
+ else
+ output_addr_const (file, addr);
+ break;
+ default:
+ output_addr_const (file, addr);
+ break;
+ }
+}
+
+
+/* Return appropriate code to load up a 1, 2, or 4 integer/floating
+ point value. */
+
+char *
+output_move_single (operands)
+ rtx *operands;
+{
+ rtx dst = operands[0];
+ rtx src = operands[1];
+
+ if (REG_P (dst))
+ {
+ if (REG_P (src))
+ return "mov %1,%0";
+
+ else if (GET_CODE (src) == CONST_INT)
+ {
+ HOST_WIDE_INT value = INTVAL (src);
+
+ if (CONST_OK_FOR_J (value)) /* signed 5 bit immediate */
+ return "mov %1,%0";
+
+ else if (CONST_OK_FOR_K (value)) /* signed 16 bit immediate */
+ return "movea lo(%1),%.,%0";
+
+ else if (CONST_OK_FOR_L (value)) /* upper 16 bits were set */
+ return "movhi hi(%1),%.,%0";
+
+ else /* random constant */
+ return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0";
+ }
+
+ else if (GET_CODE (src) == CONST_DOUBLE && GET_MODE (src) == SFmode)
+ {
+ HOST_WIDE_INT high, low;
+
+ const_double_split (src, &high, &low);
+ if (CONST_OK_FOR_J (high)) /* signed 5 bit immediate */
+ return "mov %F1,%0";
+
+ else if (CONST_OK_FOR_K (high)) /* signed 16 bit immediate */
+ return "movea lo(%F1),%.,%0";
+
+ else if (CONST_OK_FOR_L (high)) /* upper 16 bits were set */
+ return "movhi hi(%F1),%.,%0";
+
+ else /* random constant */
+ return "movhi hi(%F1),%.,%0\n\tmovea lo(%F1),%0,%0";
+ }
+
+ else if (GET_CODE (src) == MEM)
+ return "%S1ld%W1 %1,%0";
+
+ else if (special_symbolref_operand (src, VOIDmode))
+ return "movea %O1(%P1),%Q1,%0";
+
+ else if (GET_CODE (src) == LABEL_REF
+ || GET_CODE (src) == SYMBOL_REF
+ || GET_CODE (src) == CONST)
+ {
+ return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0";
+ }
+
+ else if (GET_CODE (src) == HIGH)
+ return "movhi hi(%1),%.,%0";
+
+ else if (GET_CODE (src) == LO_SUM)
+ {
+ operands[2] = XEXP (src, 0);
+ operands[3] = XEXP (src, 1);
+ return "movea lo(%3),%2,%0";
+ }
+ }
+
+ else if (GET_CODE (dst) == MEM)
+ {
+ if (REG_P (src))
+ return "%S0st%W0 %1,%0";
+
+ else if (GET_CODE (src) == CONST_INT && INTVAL (src) == 0)
+ return "%S0st%W0 %.,%0";
+
+ else if (GET_CODE (src) == CONST_DOUBLE
+ && CONST0_RTX (GET_MODE (dst)) == src)
+ return "%S0st%W0 %.,%0";
+ }
+
+ fatal_insn ("output_move_single:", gen_rtx (SET, VOIDmode, dst, src));
+ return "";
+}
+
+
+/* Return appropriate code to load up an 8 byte integer or floating point value */
+
+char *
+output_move_double (operands)
+ rtx *operands;
+{
+ enum machine_mode mode = GET_MODE (operands[0]);
+ rtx dst = operands[0];
+ rtx src = operands[1];
+
+ if (register_operand (dst, mode)
+ && register_operand (src, mode))
+ {
+ if (REGNO (src) + 1 == REGNO (dst))
+ return "mov %R1,%R0\n\tmov %1,%0";
+ else
+ return "mov %1,%0\n\tmov %R1,%R0";
+ }
+
+ /* Storing 0 */
+ if (GET_CODE (dst) == MEM
+ && ((GET_CODE (src) == CONST_INT && INTVAL (src) == 0)
+ || (GET_CODE (src) == CONST_DOUBLE && CONST_DOUBLE_OK_FOR_G (src))))
+ return "st.w %.,%0\n\tst.w %.,%R0";
+
+ if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
+ {
+ HOST_WIDE_INT high_low[2];
+ int i;
+ rtx xop[10];
+
+ if (GET_CODE (src) == CONST_DOUBLE)
+ const_double_split (src, &high_low[1], &high_low[0]);
+ else
+ {
+ high_low[0] = INTVAL (src);
+ high_low[1] = (INTVAL (src) >= 0) ? 0 : -1;
+ }
+
+ for (i = 0; i < 2; i++)
+ {
+ xop[0] = gen_rtx (REG, SImode, REGNO (dst)+i);
+ xop[1] = GEN_INT (high_low[i]);
+ output_asm_insn (output_move_single (xop), xop);
+ }
+
+ return "";
+ }
+
+ if (GET_CODE (src) == MEM)
+ {
+ int ptrreg = -1;
+ int dreg = REGNO (dst);
+ rtx inside = XEXP (src, 0);
+
+ if (GET_CODE (inside) == REG)
+ ptrreg = REGNO (inside);
+ else if (GET_CODE (inside) == SUBREG)
+ ptrreg = REGNO (SUBREG_REG (inside)) + SUBREG_WORD (inside);
+ else if (GET_CODE (inside) == PLUS)
+ ptrreg = REGNO (XEXP (inside, 0));
+ else if (GET_CODE (inside) == LO_SUM)
+ ptrreg = REGNO (XEXP (inside, 0));
+
+ if (dreg == ptrreg)
+ return "ld.w %R1,%R0\n\tld.w %1,%0";
+ }
+
+ if (GET_CODE (src) == MEM)
+ return "ld.w %1,%0\n\tld.w %R1,%R0";
+
+ if (GET_CODE (dst) == MEM)
+ return "st.w %1,%0\n\tst.w %R1,%R0";
+
+ return "mov %1,%0\n\tmov %R1,%R0";
+}
+
+
+/* Return maximum offset supported for a short EP memory reference of mode
+ MODE and signedness UNSIGNEDP. */
+
+int
+ep_memory_offset (mode, unsignedp)
+ enum machine_mode mode;
+ int unsignedp;
+{
+ int max_offset = 0;
+
+ switch (mode)
+ {
+ case QImode:
+ max_offset = (1 << 7);
+ break;
+
+ case HImode:
+ max_offset = (1 << 8);
+ break;
+
+ case SImode:
+ case SFmode:
+ max_offset = (1 << 8);
+ break;
+ }
+
+ return max_offset;
+}
+
+/* Return true if OP is a valid short EP memory reference */
+
+int
+ep_memory_operand (op, mode, unsigned_load)
+ rtx op;
+ enum machine_mode mode;
+ int unsigned_load;
+{
+ rtx addr, op0, op1;
+ int max_offset;
+ int mask;
+
+ if (GET_CODE (op) != MEM)
+ return FALSE;
+
+ max_offset = ep_memory_offset (mode, unsigned_load);
+
+ mask = GET_MODE_SIZE (mode) - 1;
+
+ addr = XEXP (op, 0);
+ if (GET_CODE (addr) == CONST)
+ addr = XEXP (addr, 0);
+
+ switch (GET_CODE (addr))
+ {
+ default:
+ break;
+
+ case SYMBOL_REF:
+ return TDA_NAME_P (XSTR (addr, 0));
+
+ case REG:
+ return REGNO (addr) == EP_REGNUM;
+
+ case PLUS:
+ op0 = XEXP (addr, 0);
+ op1 = XEXP (addr, 1);
+ if (GET_CODE (op1) == CONST_INT
+ && INTVAL (op1) < max_offset
+ && (INTVAL (op1) & mask) == 0)
+ {
+ if (GET_CODE (op0) == REG && REGNO (op0) == EP_REGNUM)
+ return TRUE;
+
+ if (GET_CODE (op0) == SYMBOL_REF && TDA_NAME_P (XSTR (op0, 0)))
+ return TRUE;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+/* Return true if OP is either a register or 0 */
+
+int
+reg_or_0_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == CONST_INT)
+ return INTVAL (op) == 0;
+
+ else if (GET_CODE (op) == CONST_DOUBLE)
+ return CONST_DOUBLE_OK_FOR_G (op);
+
+ else
+ return register_operand (op, mode);
+}
+
+/* Return true if OP is either a register or a signed five bit integer */
+
+int
+reg_or_int5_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == CONST_INT)
+ return CONST_OK_FOR_J (INTVAL (op));
+
+ else
+ return register_operand (op, mode);
+}
+
+/* Return true if OP is a valid call operand. */
+
+int
+call_address_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ /* Only registers are valid call operands if TARGET_LONG_CALLS. */
+ if (TARGET_LONG_CALLS)
+ return GET_CODE (op) == REG;
+ return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
+}
+
+int
+special_symbolref_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == SYMBOL_REF)
+ return ENCODED_NAME_P (XSTR (op, 0));
+
+ else if (GET_CODE (op) == CONST)
+ return (GET_CODE (XEXP (op, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
+ && ENCODED_NAME_P (XSTR (XEXP (XEXP (op, 0), 0), 0))
+ && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
+ && CONST_OK_FOR_K (INTVAL (XEXP (XEXP (op, 0), 1))));
+
+ return FALSE;
+}
+
+int
+movsi_source_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ /* Some constants, as well as symbolic operands
+ must be done with HIGH & LO_SUM patterns. */
+ if (CONSTANT_P (op)
+ && GET_CODE (op) != HIGH
+ && !(GET_CODE (op) == CONST_INT
+ && (CONST_OK_FOR_J (INTVAL (op))
+ || CONST_OK_FOR_K (INTVAL (op))
+ || CONST_OK_FOR_L (INTVAL (op)))))
+ return special_symbolref_operand (op, mode);
+ else
+ return general_operand (op, mode);
+}
+
+int
+power_of_two_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+
+ if (exact_log2 (INTVAL (op)) == -1)
+ return 0;
+ return 1;
+}
+
+int
+not_power_of_two_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ unsigned int mask;
+
+ if (mode == QImode)
+ mask = 0xff;
+ else if (mode == HImode)
+ mask = 0xffff;
+ else if (mode == SImode)
+ mask = 0xffffffff;
+ else
+ return 0;
+
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+
+ if (exact_log2 (~INTVAL (op) & mask) == -1)
+ return 0;
+ return 1;
+}
+
+
+/* Substitute memory references involving a pointer, to use the ep pointer,
+ taking care to save and preserve the ep. */
+
+static void
+substitute_ep_register (first_insn, last_insn, uses, regno, p_r1, p_ep)
+ rtx first_insn;
+ rtx last_insn;
+ int uses;
+ int regno;
+ rtx *p_r1;
+ rtx *p_ep;
+{
+ rtx reg = gen_rtx (REG, Pmode, regno);
+ rtx insn;
+ int i;
+
+ if (!*p_r1)
+ {
+ regs_ever_live[1] = 1;
+ *p_r1 = gen_rtx (REG, Pmode, 1);
+ *p_ep = gen_rtx (REG, Pmode, 30);
+ }
+
+ if (TARGET_DEBUG)
+ fprintf (stderr, "Saved %d bytes (%d uses of register %s) in function %s, starting as insn %d, ending at %d\n",
+ 2 * (uses - 3), uses, reg_names[regno],
+ IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
+ INSN_UID (first_insn), INSN_UID (last_insn));
+
+ if (GET_CODE (first_insn) == NOTE)
+ first_insn = next_nonnote_insn (first_insn);
+
+ last_insn = next_nonnote_insn (last_insn);
+ for (insn = first_insn; insn && insn != last_insn; insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == INSN)
+ {
+ rtx pattern = single_set (insn);
+
+ /* Replace the memory references. */
+ if (pattern)
+ {
+ rtx *p_mem;
+ /* Memory operands are signed by default. */
+ int unsignedp = FALSE;
+
+ if (GET_CODE (SET_DEST (pattern)) == MEM
+ && GET_CODE (SET_SRC (pattern)) == MEM)
+ p_mem = (rtx *)0;
+
+ else if (GET_CODE (SET_DEST (pattern)) == MEM)
+ p_mem = &SET_DEST (pattern);
+
+ else if (GET_CODE (SET_SRC (pattern)) == MEM)
+ p_mem = &SET_SRC (pattern);
+
+ else
+ p_mem = (rtx *)0;
+
+ if (p_mem)
+ {
+ rtx addr = XEXP (*p_mem, 0);
+
+ if (GET_CODE (addr) == REG && REGNO (addr) == regno)
+ *p_mem = change_address (*p_mem, VOIDmode, *p_ep);
+
+ else if (GET_CODE (addr) == PLUS
+ && GET_CODE (XEXP (addr, 0)) == REG
+ && REGNO (XEXP (addr, 0)) == regno
+ && GET_CODE (XEXP (addr, 1)) == CONST_INT
+ && (((unsigned)INTVAL (XEXP (addr, 1)))
+ < ep_memory_offset (GET_MODE (*p_mem),
+ unsignedp)))
+ *p_mem = change_address (*p_mem, VOIDmode,
+ gen_rtx (PLUS, Pmode,
+ *p_ep, XEXP (addr, 1)));
+ }
+ }
+ }
+ }
+
+ /* Optimize back to back cases of ep <- r1 & r1 <- ep. */
+ insn = prev_nonnote_insn (first_insn);
+ if (insn && GET_CODE (insn) == INSN
+ && GET_CODE (PATTERN (insn)) == SET
+ && SET_DEST (PATTERN (insn)) == *p_ep
+ && SET_SRC (PATTERN (insn)) == *p_r1)
+ delete_insn (insn);
+ else
+ emit_insn_before (gen_rtx (SET, Pmode, *p_r1, *p_ep), first_insn);
+
+ emit_insn_before (gen_rtx (SET, Pmode, *p_ep, reg), first_insn);
+ emit_insn_before (gen_rtx (SET, Pmode, *p_ep, *p_r1), last_insn);
+}
+
+
+/* In rare cases, correct code generation requires extra machine
+ dependent processing between the second jump optimization pass and
+ delayed branch scheduling. On those machines, define this macro
+ as a C statement to act on the code starting at INSN.
+
+ On the 850, we use it to implement the -mep mode to copy heavily used
+ pointers to ep to use the implicit addressing */
+
+void v850_reorg (start_insn)
+ rtx start_insn;
+{
+ struct {
+ int uses;
+ rtx first_insn;
+ rtx last_insn;
+ } regs[FIRST_PSEUDO_REGISTER];
+
+ int i;
+ int use_ep = FALSE;
+ rtx r1 = NULL_RTX;
+ rtx ep = NULL_RTX;
+ rtx insn;
+ rtx pattern;
+
+ /* If not ep mode, just return now */
+ if (!TARGET_EP)
+ return;
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ {
+ regs[i].uses = 0;
+ regs[i].first_insn = NULL_RTX;
+ regs[i].last_insn = NULL_RTX;
+ }
+
+ for (insn = start_insn; insn != NULL_RTX; insn = NEXT_INSN (insn))
+ {
+ switch (GET_CODE (insn))
+ {
+ /* End of basic block */
+ default:
+ if (!use_ep)
+ {
+ int max_uses = -1;
+ int max_regno = -1;
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ {
+ if (max_uses < regs[i].uses)
+ {
+ max_uses = regs[i].uses;
+ max_regno = i;
+ }
+ }
+
+ if (max_uses > 3)
+ substitute_ep_register (regs[max_regno].first_insn,
+ regs[max_regno].last_insn,
+ max_uses, max_regno, &r1, &ep);
+ }
+
+ use_ep = FALSE;
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ {
+ regs[i].uses = 0;
+ regs[i].first_insn = NULL_RTX;
+ regs[i].last_insn = NULL_RTX;
+ }
+ break;
+
+ case NOTE:
+ break;
+
+ case INSN:
+ pattern = single_set (insn);
+
+ /* See if there are any memory references we can shorten */
+ if (pattern)
+ {
+ rtx src = SET_SRC (pattern);
+ rtx dest = SET_DEST (pattern);
+ rtx mem;
+ /* Memory operands are signed by default. */
+ int unsignedp = FALSE;
+
+ if (GET_CODE (dest) == MEM && GET_CODE (src) == MEM)
+ mem = NULL_RTX;
+
+ else if (GET_CODE (dest) == MEM)
+ mem = dest;
+
+ else if (GET_CODE (src) == MEM)
+ mem = src;
+
+ else
+ mem = NULL_RTX;
+
+ if (mem && ep_memory_operand (mem, GET_MODE (mem), unsignedp))
+ use_ep = TRUE;
+
+ else if (!use_ep && mem
+ && GET_MODE_SIZE (GET_MODE (mem)) <= UNITS_PER_WORD)
+ {
+ rtx addr = XEXP (mem, 0);
+ int regno = -1;
+ int short_p;
+
+ if (GET_CODE (addr) == REG)
+ {
+ short_p = TRUE;
+ regno = REGNO (addr);
+ }
+
+ else if (GET_CODE (addr) == PLUS
+ && GET_CODE (XEXP (addr, 0)) == REG
+ && GET_CODE (XEXP (addr, 1)) == CONST_INT
+ && (((unsigned)INTVAL (XEXP (addr, 1)))
+ < ep_memory_offset (GET_MODE (mem), unsignedp)))
+ {
+ short_p = TRUE;
+ regno = REGNO (XEXP (addr, 0));
+ }
+
+ else
+ short_p = FALSE;
+
+ if (short_p)
+ {
+ regs[regno].uses++;
+ regs[regno].last_insn = insn;
+ if (!regs[regno].first_insn)
+ regs[regno].first_insn = insn;
+ }
+ }
+
+ /* Loading up a register in the basic block zaps any savings
+ for the register */
+ if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
+ {
+ enum machine_mode mode = GET_MODE (dest);
+ int word = 0;
+ int regno;
+ int endregno;
+
+ while (GET_CODE (dest) == SUBREG)
+ {
+ word = SUBREG_WORD (dest);
+ dest = SUBREG_REG (dest);
+ }
+
+ regno = REGNO (dest) + word;
+ endregno = regno + HARD_REGNO_NREGS (regno, mode);
+
+ if (!use_ep)
+ {
+ /* See if we can use the pointer before this
+ modification. */
+ int max_uses = -1;
+ int max_regno = -1;
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ {
+ if (max_uses < regs[i].uses)
+ {
+ max_uses = regs[i].uses;
+ max_regno = i;
+ }
+ }
+
+ if (max_uses > 3
+ && max_regno >= regno
+ && max_regno < endregno)
+ {
+ substitute_ep_register (regs[max_regno].first_insn,
+ regs[max_regno].last_insn,
+ max_uses, max_regno, &r1, &ep);
+
+ /* Since we made a substitution, zap all remembered
+ registers. */
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ {
+ regs[i].uses = 0;
+ regs[i].first_insn = NULL_RTX;
+ regs[i].last_insn = NULL_RTX;
+ }
+ }
+ }
+
+ for (i = regno; i < endregno; i++)
+ {
+ regs[i].uses = 0;
+ regs[i].first_insn = NULL_RTX;
+ regs[i].last_insn = NULL_RTX;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+/* # of registers saved by the interrupt handler. */
+#define INTERRUPT_FIXED_NUM 4
+
+/* # of bytes for registers saved by the interrupt handler. */
+#define INTERRUPT_FIXED_SAVE_SIZE (4 * INTERRUPT_FIXED_NUM)
+
+/* # of registers saved in register parameter area. */
+#define INTERRUPT_REGPARM_NUM 4
+/* # of words saved for other registers. */
+#define INTERRUPT_ALL_SAVE_NUM \
+ (30 - INTERRUPT_FIXED_NUM + INTERRUPT_REGPARM_NUM)
+
+#define INTERRUPT_ALL_SAVE_SIZE (4 * INTERRUPT_ALL_SAVE_NUM)
+
+int
+compute_register_save_size (p_reg_saved)
+ long *p_reg_saved;
+{
+ int size = 0;
+ int i;
+ int interrupt_handler = v850_interrupt_function_p (current_function_decl);
+ int call_p = regs_ever_live[31];
+ long reg_saved = 0;
+
+ /* Count the return pointer if we need to save it. */
+ if (profile_flag && !call_p)
+ regs_ever_live[31] = call_p = 1;
+
+ /* Count space for the register saves. */
+ if (interrupt_handler)
+ {
+ for (i = 0; i <= 31; i++)
+ switch (i)
+ {
+ default:
+ if (regs_ever_live[i] || call_p)
+ {
+ size += 4;
+ reg_saved |= 1L << i;
+ }
+ break;
+
+ /* We don't save/restore r0 or the stack pointer */
+ case 0:
+ case STACK_POINTER_REGNUM:
+ break;
+
+ /* For registers with fixed use, we save them, set them to the
+ appropriate value, and then restore them.
+ These registers are handled specially, so don't list them
+ on the list of registers to save in the prologue. */
+ case 1: /* temp used to hold ep */
+ case 4: /* gp */
+ case 10: /* temp used to call interrupt save/restore */
+ case EP_REGNUM: /* ep */
+ size += 4;
+ break;
+ }
+ }
+
+ else
+ for (i = 0; i <= 31; i++)
+ if (regs_ever_live[i] && ((! call_used_regs[i]) || i == 31))
+ {
+ size += 4;
+ reg_saved |= 1L << i;
+ }
+
+ if (p_reg_saved)
+ *p_reg_saved = reg_saved;
+
+ return size;
+}
+
+int
+compute_frame_size (size, p_reg_saved)
+ int size;
+ long *p_reg_saved;
+{
+ extern int current_function_outgoing_args_size;
+
+ return (size
+ + compute_register_save_size (p_reg_saved)
+ + current_function_outgoing_args_size);
+}
+
+
+void
+expand_prologue ()
+{
+ unsigned int i;
+ int offset;
+ unsigned int size = get_frame_size ();
+ unsigned int actual_fsize;
+ unsigned int init_stack_alloc = 0;
+ rtx save_regs[32];
+ rtx save_all;
+ int num_save;
+ int default_stack;
+ int code;
+ int interrupt_handler = v850_interrupt_function_p (current_function_decl);
+ long reg_saved = 0;
+
+ actual_fsize = compute_frame_size (size, &reg_saved);
+
+ /* Save/setup global registers for interrupt functions right now */
+ if (interrupt_handler)
+ {
+ emit_insn (gen_save_interrupt ());
+ actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE;
+ if (((1L << 31) & reg_saved) != 0)
+ actual_fsize -= INTERRUPT_ALL_SAVE_SIZE;
+ }
+
+ /* Save arg registers to the stack if necessary. */
+ else if (current_function_anonymous_args)
+ {
+ if (TARGET_PROLOG_FUNCTION)
+ emit_insn (gen_save_r6_r9 ());
+ else
+ {
+ offset = 0;
+ for (i = 6; i < 10; i++)
+ {
+ emit_move_insn (gen_rtx (MEM, SImode,
+ plus_constant (stack_pointer_rtx,
+ offset)),
+ gen_rtx (REG, SImode, i));
+ offset += 4;
+ }
+ }
+ }
+
+ /* Identify all of the saved registers */
+ num_save = 0;
+ default_stack = 0;
+ for (i = 1; i < 31; i++)
+ {
+ if (((1L << i) & reg_saved) != 0)
+ save_regs[num_save++] = gen_rtx (REG, Pmode, i);
+ }
+
+ /* If the return pointer is saved, the helper functions also allocate
+ 16 bytes of stack for arguments to be saved in. */
+ if (((1L << 31) & reg_saved) != 0)
+ {
+ save_regs[num_save++] = gen_rtx (REG, Pmode, 31);
+ default_stack = 16;
+ }
+
+ /* See if we have an insn that allocates stack space and saves the particular
+ registers we want to. */
+ save_all = NULL_RTX;
+ if (TARGET_PROLOG_FUNCTION && num_save > 0 && actual_fsize >= default_stack)
+ {
+ int alloc_stack = (4 * num_save) + default_stack;
+ int unalloc_stack = actual_fsize - alloc_stack;
+ int save_func_len = 4;
+ int save_normal_len;
+
+ if (unalloc_stack)
+ save_func_len += CONST_OK_FOR_J (unalloc_stack) ? 2 : 4;
+
+ /* see if we would have used ep to save the stack */
+ if (TARGET_EP && num_save > 3 && (unsigned)actual_fsize < 255)
+ save_normal_len = (3 * 2) + (2 * num_save);
+ else
+ save_normal_len = 4 * num_save;
+
+ save_normal_len += CONST_OK_FOR_J (actual_fsize) ? 2 : 4;
+
+ /* Don't bother checking if we don't actually save any space.
+ This happens for instance if one register is saved and additional
+ stack space is allocated. */
+ if (save_func_len < save_normal_len)
+ {
+ save_all = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (num_save + (TARGET_V850 ? 2 : 1)));
+ XVECEXP (save_all, 0, 0) = gen_rtx (SET, VOIDmode,
+ stack_pointer_rtx,
+ gen_rtx (PLUS, Pmode,
+ stack_pointer_rtx,
+ GEN_INT (-alloc_stack)));
+
+ if (TARGET_V850)
+ {
+ XVECEXP (save_all, 0, num_save+1)
+ = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 10));
+ }
+
+ offset = - default_stack;
+ for (i = 0; i < num_save; i++)
+ {
+ XVECEXP (save_all, 0, i+1)
+ = gen_rtx (SET, VOIDmode,
+ gen_rtx (MEM, Pmode,
+ plus_constant (stack_pointer_rtx, offset)),
+ save_regs[i]);
+ offset -= 4;
+ }
+
+ code = recog (save_all, NULL_RTX, NULL_PTR);
+ if (code >= 0)
+ {
+ rtx insn = emit_insn (save_all);
+ INSN_CODE (insn) = code;
+ actual_fsize -= alloc_stack;
+
+ if (TARGET_DEBUG)
+ fprintf (stderr, "Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
+ save_normal_len - save_func_len,
+ save_normal_len, save_func_len,
+ IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
+ }
+ else
+ save_all = NULL_RTX;
+ }
+ }
+
+ /* If no prolog save function is available, store the registers the old fashioned
+ way (one by one). */
+ if (!save_all)
+ {
+ /* Special case interrupt functions that save all registers for a call. */
+ if (interrupt_handler && ((1L << 31) & reg_saved) != 0)
+ emit_insn (gen_save_all_interrupt ());
+
+ else
+ {
+ /* If the stack is too big, allocate it in chunks so we can do the
+ register saves. We use the register save size so we use the ep
+ register. */
+ if (actual_fsize && !CONST_OK_FOR_K (-actual_fsize))
+ init_stack_alloc = compute_register_save_size (NULL);
+ else
+ init_stack_alloc = actual_fsize;
+
+ /* Save registers at the beginning of the stack frame */
+ offset = init_stack_alloc - 4;
+
+ if (init_stack_alloc)
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT (-init_stack_alloc)));
+
+ /* Save the return pointer first. */
+ if (num_save > 0 && REGNO (save_regs[num_save-1]) == 31)
+ {
+ emit_move_insn (gen_rtx (MEM, SImode,
+ plus_constant (stack_pointer_rtx,
+ offset)),
+ save_regs[--num_save]);
+ offset -= 4;
+ }
+
+ for (i = 0; i < num_save; i++)
+ {
+ emit_move_insn (gen_rtx (MEM, SImode,
+ plus_constant (stack_pointer_rtx,
+ offset)),
+ save_regs[i]);
+ offset -= 4;
+ }
+ }
+ }
+
+ /* Allocate the rest of the stack that was not allocated above (either it is
+ > 32K or we just called a function to save the registers and needed more
+ stack. */
+ if (actual_fsize > init_stack_alloc)
+ {
+ int diff = actual_fsize - init_stack_alloc;
+ if (CONST_OK_FOR_K (diff))
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT (-diff)));
+ else
+ {
+ rtx reg = gen_rtx (REG, Pmode, 12);
+ emit_move_insn (reg, GEN_INT (-diff));
+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, reg));
+ }
+ }
+
+ /* If we need a frame pointer, set it up now. */
+ if (frame_pointer_needed)
+ emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
+}
+
+
+void
+expand_epilogue ()
+{
+ unsigned int i;
+ int offset;
+ unsigned int size = get_frame_size ();
+ long reg_saved = 0;
+ unsigned int actual_fsize = compute_frame_size (size, &reg_saved);
+ unsigned int init_stack_free = 0;
+ rtx restore_regs[32];
+ rtx restore_all;
+ int num_restore;
+ int default_stack;
+ int code;
+ int interrupt_handler = v850_interrupt_function_p (current_function_decl);
+
+ /* Eliminate the initial stack stored by interrupt functions. */
+ if (interrupt_handler)
+ {
+ actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE;
+ if (((1L << 31) & reg_saved) != 0)
+ actual_fsize -= INTERRUPT_ALL_SAVE_SIZE;
+ }
+
+ /* Cut off any dynamic stack created. */
+ if (frame_pointer_needed)
+ emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
+
+ /* Identify all of the saved registers */
+ num_restore = 0;
+ default_stack = 0;
+ for (i = 1; i < 31; i++)
+ {
+ if (((1L << i) & reg_saved) != 0)
+ restore_regs[num_restore++] = gen_rtx (REG, Pmode, i);
+ }
+
+ /* If the return pointer is saved, the helper functions also allocate
+ 16 bytes of stack for arguments to be saved in. */
+ if (((1L << 31) & reg_saved) != 0)
+ {
+ restore_regs[num_restore++] = gen_rtx (REG, Pmode, 31);
+ default_stack = 16;
+ }
+
+ /* See if we have an insn that restores the particular registers we
+ want to. */
+ restore_all = NULL_RTX;
+ if (TARGET_PROLOG_FUNCTION && num_restore > 0 && actual_fsize >= default_stack
+ && !interrupt_handler)
+ {
+ int alloc_stack = (4 * num_restore) + default_stack;
+ int unalloc_stack = actual_fsize - alloc_stack;
+ int restore_func_len = 4;
+ int restore_normal_len;
+
+ if (unalloc_stack)
+ restore_func_len += CONST_OK_FOR_J (unalloc_stack) ? 2 : 4;
+
+ /* see if we would have used ep to restore the registers */
+ if (TARGET_EP && num_restore > 3 && (unsigned)actual_fsize < 255)
+ restore_normal_len = (3 * 2) + (2 * num_restore);
+ else
+ restore_normal_len = 4 * num_restore;
+
+ restore_normal_len += (CONST_OK_FOR_J (actual_fsize) ? 2 : 4) + 2;
+
+ /* Don't bother checking if we don't actually save any space. */
+ if (restore_func_len < restore_normal_len)
+ {
+ restore_all = gen_rtx (PARALLEL, VOIDmode,
+ rtvec_alloc (num_restore + 2));
+ XVECEXP (restore_all, 0, 0) = gen_rtx (RETURN, VOIDmode);
+ XVECEXP (restore_all, 0, 1)
+ = gen_rtx (SET, VOIDmode, stack_pointer_rtx,
+ gen_rtx (PLUS, Pmode,
+ stack_pointer_rtx,
+ GEN_INT (alloc_stack)));
+
+ offset = alloc_stack - 4;
+ for (i = 0; i < num_restore; i++)
+ {
+ XVECEXP (restore_all, 0, i+2)
+ = gen_rtx (SET, VOIDmode,
+ restore_regs[i],
+ gen_rtx (MEM, Pmode,
+ plus_constant (stack_pointer_rtx, offset)));
+ offset -= 4;
+ }
+
+ code = recog (restore_all, NULL_RTX, NULL_PTR);
+ if (code >= 0)
+ {
+ rtx insn;
+
+ actual_fsize -= alloc_stack;
+ if (actual_fsize)
+ {
+ if (CONST_OK_FOR_K (actual_fsize))
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT (actual_fsize)));
+ else
+ {
+ rtx reg = gen_rtx (REG, Pmode, 12);
+ emit_move_insn (reg, GEN_INT (actual_fsize));
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ reg));
+ }
+ }
+
+ insn = emit_jump_insn (restore_all);
+ INSN_CODE (insn) = code;
+
+ if (TARGET_DEBUG)
+ fprintf (stderr, "Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
+ restore_normal_len - restore_func_len,
+ restore_normal_len, restore_func_len,
+ IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
+ }
+ else
+ restore_all = NULL_RTX;
+ }
+ }
+
+ /* If no epilog save function is available, restore the registers the
+ old fashioned way (one by one). */
+ if (!restore_all)
+ {
+ /* If the stack is large, we need to cut it down in 2 pieces. */
+ if (actual_fsize && !CONST_OK_FOR_K (-actual_fsize))
+ init_stack_free = 4 * num_restore;
+ else
+ init_stack_free = actual_fsize;
+
+ /* Deallocate the rest of the stack if it is > 32K or if extra stack
+ was allocated for an interrupt handler that makes a call. */
+ if (actual_fsize > init_stack_free || (interrupt_handler && actual_fsize))
+ {
+ int diff = actual_fsize - ((interrupt_handler) ? 0 : init_stack_free);
+ if (CONST_OK_FOR_K (diff))
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT (diff)));
+ else
+ {
+ rtx reg = gen_rtx (REG, Pmode, 12);
+ emit_move_insn (reg, GEN_INT (diff));
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ reg));
+ }
+ }
+
+ /* Special case interrupt functions that save all registers
+ for a call. */
+ if (interrupt_handler && ((1L << 31) & reg_saved) != 0)
+ emit_insn (gen_restore_all_interrupt ());
+ else
+ {
+ /* Restore registers from the beginning of the stack frame */
+ offset = init_stack_free - 4;
+
+ /* Restore the return pointer first. */
+ if (num_restore > 0 && REGNO (restore_regs[num_restore-1]) == 31)
+ {
+ emit_move_insn (restore_regs[--num_restore],
+ gen_rtx (MEM, SImode,
+ plus_constant (stack_pointer_rtx,
+ offset)));
+ offset -= 4;
+ }
+
+ for (i = 0; i < num_restore; i++)
+ {
+ emit_move_insn (restore_regs[i],
+ gen_rtx (MEM, SImode,
+ plus_constant (stack_pointer_rtx,
+ offset)));
+
+ offset -= 4;
+ }
+
+ /* Cut back the remainder of the stack. */
+ if (init_stack_free)
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT (init_stack_free)));
+ }
+
+ /* And return or use reti for interrupt handlers. */
+ if (interrupt_handler)
+ emit_jump_insn (gen_restore_interrupt ());
+ else if (actual_fsize)
+ emit_jump_insn (gen_return_internal ());
+ else
+ emit_jump_insn (gen_return ());
+ }
+
+ current_function_anonymous_args = 0;
+ v850_interrupt_cache_p = FALSE;
+ v850_interrupt_p = FALSE;
+}
+
+
+/* Update the condition code from the insn. */
+
+void
+notice_update_cc (body, insn)
+ rtx body;
+ rtx insn;
+{
+ switch (get_attr_cc (insn))
+ {
+ case CC_NONE:
+ /* Insn does not affect CC at all. */
+ break;
+
+ case CC_NONE_0HIT:
+ /* Insn does not change CC, but the 0'th operand has been changed. */
+ if (cc_status.value1 != 0
+ && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
+ cc_status.value1 = 0;
+ break;
+
+ case CC_SET_ZN:
+ /* Insn sets the Z,N flags of CC to recog_operand[0].
+ V,C is in an unusable state. */
+ CC_STATUS_INIT;
+ cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
+ cc_status.value1 = recog_operand[0];
+ break;
+
+ case CC_SET_ZNV:
+ /* Insn sets the Z,N,V flags of CC to recog_operand[0].
+ C is in an unusable state. */
+ CC_STATUS_INIT;
+ cc_status.flags |= CC_NO_CARRY;
+ cc_status.value1 = recog_operand[0];
+ break;
+
+ case CC_COMPARE:
+ /* The insn is a compare instruction. */
+ CC_STATUS_INIT;
+ cc_status.value1 = SET_SRC (body);
+ break;
+
+ case CC_CLOBBER:
+ /* Insn doesn't leave CC in a usable state. */
+ CC_STATUS_INIT;
+ break;
+ }
+}
+
+
+/* Return nonzero if ATTR is a valid attribute for DECL.
+ ATTRIBUTES are any existing attributes and ARGS are the arguments
+ supplied with ATTR.
+
+ Supported attributes:
+
+ interrupt_handler or interrupt: output a prologue and epilogue suitable
+ for an interrupt handler. */
+
+int
+v850_valid_machine_decl_attribute (decl, attributes, attr, args)
+ tree decl;
+ tree attributes;
+ tree attr;
+ tree args;
+{
+ if (args != NULL_TREE)
+ return 0;
+
+ if (is_attribute_p ("interrupt_handler", attr)
+ || is_attribute_p ("interrupt", attr))
+ return TREE_CODE (decl) == FUNCTION_DECL;
+
+ return 0;
+}
+
+
+/* Return nonzero if FUNC is an interrupt function as specified
+ by the "interrupt" attribute. */
+
+int
+v850_interrupt_function_p (func)
+ tree func;
+{
+ tree a;
+ int ret = 0;
+
+ if (v850_interrupt_cache_p)
+ return v850_interrupt_p;
+
+ if (TREE_CODE (func) != FUNCTION_DECL)
+ return 0;
+
+ a = lookup_attribute ("interrupt_handler", DECL_MACHINE_ATTRIBUTES (func));
+ if (a != NULL_TREE)
+ ret = 1;
+
+ else
+ {
+ a = lookup_attribute ("interrupt", DECL_MACHINE_ATTRIBUTES (func));
+ ret = a != NULL_TREE;
+ }
+
+ /* Its not safe to trust global variables until after function inlining has
+ been done. */
+ if (reload_completed | reload_in_progress)
+ v850_interrupt_p = ret;
+
+ return ret;
+}
+
+
+extern struct obstack *saveable_obstack;
+
+v850_encode_data_area (decl)
+ tree decl;
+{
+ char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+ int len = strlen (str);
+ char *newstr;
+
+ /* In the Cygnus sources we actually do something; this is just
+ here to make merges easier. */
+ return;
+}
+
+/* Return true if the given RTX is a register which can be restored
+ by a function epilogue. */
+int
+register_is_ok_for_epilogue (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ /* The save/restore routines can only cope with registers 2, and 20 - 31 */
+ return (GET_CODE (op) == REG)
+ && (((REGNO (op) >= 20) && REGNO (op) <= 31)
+ || REGNO (op) == 2);
+}
+
+/* Return non-zero if the given RTX is suitable for collapsing into
+ jump to a function epilogue. */
+int
+pattern_is_ok_for_epilogue (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ int count = XVECLEN (op, 0);
+ int i;
+
+ /* If there are no registers to restore then the function epilogue
+ is not suitable. */
+ if (count <= 2)
+ return 0;
+
+ /* The pattern matching has already established that we are performing a
+ function epilogue and that we are popping at least one register. We must
+ now check the remaining entries in the vector to make sure that they are
+ also register pops. There is no good reason why there should ever be
+ anything else in this vector, but being paranoid always helps...
+
+ The test below performs the C equivalent of this machine description
+ pattern match:
+
+ (set (match_operand:SI n "register_is_ok_for_epilogue" "r")
+ (mem:SI (plus:SI (reg:SI 3) (match_operand:SI n "immediate_operand" "i"))))
+ */
+
+ for (i = 3; i < count; i++)
+ {
+ rtx vector_element = XVECEXP (op, 0, i);
+ rtx dest;
+ rtx src;
+ rtx plus;
+
+ if (GET_CODE (vector_element) != SET)
+ return 0;
+
+ dest = SET_DEST (vector_element);
+ src = SET_SRC (vector_element);
+
+ if (GET_CODE (dest) != REG
+ || GET_MODE (dest) != SImode
+ || ! register_is_ok_for_epilogue (dest, SImode)
+ || GET_CODE (src) != MEM
+ || GET_MODE (src) != SImode)
+ return 0;
+
+ plus = XEXP (src, 0);
+
+ if (GET_CODE (plus) != PLUS
+ || GET_CODE (XEXP (plus, 0)) != REG
+ || GET_MODE (XEXP (plus, 0)) != SImode
+ || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
+ || GET_CODE (XEXP (plus, 1)) != CONST_INT)
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Construct a JR instruction to a routine that will perform the equivalent of
+ the RTL passed in as an argument. This RTL is a function epilogue that
+ pops registers off the stack and possibly releases some extra stack space
+ as well. The code has already verified that the RTL matches these
+ requirements. */
+char *
+construct_restore_jr (op)
+ rtx op;
+{
+ int count = XVECLEN (op, 0);
+ int stack_bytes;
+ unsigned long int mask;
+ unsigned long int first;
+ unsigned long int last;
+ int i;
+ static char buff [100]; /* XXX */
+
+ if (count <= 2)
+ {
+ error ("Bogus JR construction: %d\n", count);
+ return NULL;
+ }
+
+ /* Work out how many bytes to pop off the stack before retrieving
+ registers. */
+ if (GET_CODE (XVECEXP (op, 0, 1)) != SET)
+ abort ();
+ if (GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) != PLUS)
+ abort ();
+ if (GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1)) != CONST_INT)
+ abort ();
+
+ stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1));
+
+ /* Each pop will remove 4 bytes from the stack... */
+ stack_bytes -= (count - 2) * 4;
+
+ /* Make sure that the amount we are popping either 0 or 16 bytes. */
+ if (stack_bytes != 0 && stack_bytes != 16)
+ {
+ error ("Bad amount of stack space removal: %d", stack_bytes);
+ return NULL;
+ }
+
+ /* Now compute the bit mask of registers to push. */
+ mask = 0;
+ for (i = 2; i < count; i++)
+ {
+ rtx vector_element = XVECEXP (op, 0, i);
+
+ if (GET_CODE (vector_element) != SET)
+ abort ();
+ if (GET_CODE (SET_DEST (vector_element)) != REG)
+ abort ();
+ if (! register_is_ok_for_epilogue (SET_DEST (vector_element), SImode))
+ abort ();
+
+ mask |= 1 << REGNO (SET_DEST (vector_element));
+ }
+
+ /* Scan for the first register to pop. */
+ for (first = 0; first < 32; first++)
+ {
+ if (mask & (1 << first))
+ break;
+ }
+
+ if (first >= 32)
+ abort ();
+
+ /* Discover the last register to pop. */
+ if (mask & (1 << 31))
+ {
+ if (stack_bytes != 16)
+ abort ();
+
+ last = 31;
+ }
+ else
+ {
+ if (stack_bytes != 0)
+ abort ();
+ if ((mask & (1 << 29)) == 0)
+ abort ();
+
+ last = 29;
+ }
+
+ /* Paranoia */
+ for (i = (first == 2 ? 20 : first + 1); i < 29; i++)
+ if ((mask & (1 << i)) == 0)
+ abort ();
+
+ if (first == last)
+ sprintf (buff, "jr __return_%s", reg_names [first]);
+ else
+ sprintf (buff, "jr __return_%s_%s", reg_names [first], reg_names [last]);
+
+ return buff;
+}
+
+
+/* Return non-zero if the given RTX is suitable for collapsing into
+ a jump to a function prologue. */
+int
+pattern_is_ok_for_prologue (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ int count = XVECLEN (op, 0);
+ int i;
+ rtx vector_element;
+
+ /* If there are no registers to save then the function prologue
+ is not suitable. */
+ if (count <= 2)
+ return 0;
+
+ /* The pattern matching has already established that we are adjusting the
+ stack and pushing at least one register. We must now check that the
+ remaining entries in the vector to make sure that they are also register
+ pushes, except for the last entry which should be a CLOBBER of r10.
+
+ The test below performs the C equivalent of this machine description
+ pattern match:
+
+ (set (mem:SI (plus:SI (reg:SI 3)
+ (match_operand:SI 2 "immediate_operand" "i")))
+ (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))
+
+ */
+
+ for (i = 2; i < count - 1; i++)
+ {
+ rtx dest;
+ rtx src;
+ rtx plus;
+
+ vector_element = XVECEXP (op, 0, i);
+
+ if (GET_CODE (vector_element) != SET)
+ return 0;
+
+ dest = SET_DEST (vector_element);
+ src = SET_SRC (vector_element);
+
+ if (GET_CODE (dest) != MEM
+ || GET_MODE (dest) != SImode
+ || GET_CODE (src) != REG
+ || GET_MODE (src) != SImode
+ || ! register_is_ok_for_epilogue (src, SImode))
+ return 0;
+
+ plus = XEXP (dest, 0);
+
+ if ( GET_CODE (plus) != PLUS
+ || GET_CODE (XEXP (plus, 0)) != REG
+ || GET_MODE (XEXP (plus, 0)) != SImode
+ || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
+ || GET_CODE (XEXP (plus, 1)) != CONST_INT)
+ return 0;
+
+ /* If the register is being pushed somewhere other than the stack
+ space just acquired by the first operand then abandon this quest.
+ Note: the test is <= because both values are negative. */
+ if (INTVAL (XEXP (plus, 1))
+ <= INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)))
+ {
+ return 0;
+ }
+ }
+
+ /* Make sure that the last entry in the vector is a clobber. */
+ vector_element = XVECEXP (op, 0, i);
+
+ if (GET_CODE (vector_element) != CLOBBER
+ || GET_CODE (XEXP (vector_element, 0)) != REG
+ || REGNO (XEXP (vector_element, 0)) != 10)
+ return 0;
+
+ return 1;
+}
+
+/* Construct a JARL instruction to a routine that will perform the equivalent
+ of the RTL passed as a parameter. This RTL is a function prologue that
+ saves some of the registers r20 - r31 onto the stack, and possibly acquires
+ some stack space as well. The code has already verified that the RTL
+ matches these requirements. */
+char *
+construct_save_jarl (op)
+ rtx op;
+{
+ int count = XVECLEN (op, 0);
+ int stack_bytes;
+ unsigned long int mask;
+ unsigned long int first;
+ unsigned long int last;
+ int i;
+ static char buff [100]; /* XXX */
+
+ if (count <= 2)
+ {
+ error ("Bogus JARL construction: %d\n", count);
+ return NULL;
+ }
+
+ /* Paranoia. */
+ if (GET_CODE (XVECEXP (op, 0, 0)) != SET)
+ abort ();
+ if (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != PLUS)
+ abort ();
+ if (GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0)) != REG)
+ abort ();
+ if (GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)) != CONST_INT)
+ abort ();
+
+ /* Work out how many bytes to push onto the stack after storing the
+ registers. */
+ stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1));
+
+ /* Each push will put 4 bytes from the stack... */
+ stack_bytes += (count - 2) * 4;
+
+ /* Make sure that the amount we are popping either 0 or 16 bytes. */
+ if (stack_bytes != 0 && stack_bytes != -16)
+ {
+ error ("Bad amount of stack space removal: %d", stack_bytes);
+ return NULL;
+ }
+
+ /* Now compute the bit mask of registers to push. */
+ mask = 0;
+ for (i = 1; i < count - 1; i++)
+ {
+ rtx vector_element = XVECEXP (op, 0, i);
+
+ if (GET_CODE (vector_element) != SET)
+ abort ();
+ if (GET_CODE (SET_SRC (vector_element)) != REG)
+ abort ();
+ if (! register_is_ok_for_epilogue (SET_SRC (vector_element), SImode))
+ abort ();
+
+ mask |= 1 << REGNO (SET_SRC (vector_element));
+ }
+
+ /* Scan for the first register to push. */
+ for (first = 0; first < 32; first++)
+ {
+ if (mask & (1 << first))
+ break;
+ }
+
+ if (first >= 32)
+ abort ();
+
+ /* Discover the last register to push. */
+ if (mask & (1 << 31))
+ {
+ if (stack_bytes != -16)
+ abort();
+
+ last = 31;
+ }
+ else
+ {
+ if (stack_bytes != 0)
+ abort ();
+ if ((mask & (1 << 29)) == 0)
+ abort ();
+
+ last = 29;
+ }
+
+ /* Paranoia */
+ for (i = (first == 2 ? 20 : first + 1); i < 29; i++)
+ if ((mask & (1 << i)) == 0)
+ abort ();
+
+ if (first == last)
+ sprintf (buff, "jarl __save_%s, r10", reg_names [first]);
+ else
+ sprintf (buff, "jarl __save_%s_%s, r10", reg_names [first],
+ reg_names [last]);
+
+ return buff;
+}
+
diff --git a/gnu/usr.bin/gcc/config/v850/v850.h b/gnu/usr.bin/gcc/config/v850/v850.h
new file mode 100644
index 00000000000..19eab5fdaf8
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/v850/v850.h
@@ -0,0 +1,1475 @@
+/* Definitions of target machine for GNU compiler. NEC V850 series
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Jeff Law (law@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 "svr4.h" /* Automatically does #undef CPP_PREDEFINES */
+
+#undef ASM_SPEC
+#define ASM_SPEC "%{mv*:-mv%*}"
+
+#ifndef CPP_SPEC
+#define CPP_SPEC "-D__v850__"
+#endif
+
+#undef ASM_FINAL_SPEC
+#undef LIB_SPEC
+#undef ENDFILE_SPEC
+#undef LINK_SPEC
+#undef STARTFILE_SPEC
+
+/* Names to predefine in the preprocessor for this target machine. */
+#define CPP_PREDEFINES "-D__v851__ -D__v850"
+
+/* Print subsidiary information on the compiler version in use. */
+
+#ifndef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (NEC V850)");
+#endif
+
+
+/* Run-time compilation parameters selecting different hardware subsets. */
+
+extern int target_flags;
+
+/* Target flags bits, see below for an explanation of the bits. */
+#define MASK_GHS 0x00000001
+#define MASK_LONG_CALLS 0x00000002
+#define MASK_EP 0x00000004
+#define MASK_PROLOG_FUNCTION 0x00000008
+#define MASK_DEBUG 0x40000000
+
+#define MASK_CPU 0x00000030
+#define MASK_V850 0x00000010
+
+#define MASK_BIG_SWITCH 0x00000100
+
+#ifndef MASK_DEFAULT
+#define MASK_DEFAULT MASK_V850
+#endif
+
+#define TARGET_V850 ((target_flags & MASK_CPU) == MASK_V850)
+
+
+/* Macros used in the machine description to test the flags. */
+
+/* The GHS calling convention support doesn't really work,
+ mostly due to a lack of documentation. Outstanding issues:
+
+ * How do varargs & stdarg really work. How to they handle
+ passing structures (if at all).
+
+ * Doubles are normally 4 byte aligned, except in argument
+ lists where they are 8 byte aligned. Is the alignment
+ in the argument list based on the first parameter,
+ first stack parameter, etc etc.
+
+ * Passing/returning of large structures probably isn't the same
+ as GHS. We don't have enough documentation on their conventions
+ to be compatible.
+
+ * Tests of SETUP_INCOMING_VARARGS need to be made runtime checks
+ since it depends on TARGET_GHS. */
+#define TARGET_GHS (target_flags & MASK_GHS)
+
+/* Don't do PC-relative calls, instead load the address of the target
+ function into a register and perform a register indirect call. */
+#define TARGET_LONG_CALLS (target_flags & MASK_LONG_CALLS)
+
+/* Whether to optimize space by using ep (r30) for pointers with small offsets
+ in basic blocks. */
+#define TARGET_EP (target_flags & MASK_EP)
+
+/* Whether to call out-of-line functions to save registers or not. */
+#define TARGET_PROLOG_FUNCTION (target_flags & MASK_PROLOG_FUNCTION)
+
+/* Whether to emit 2 byte per entry or 4 byte per entry switch tables. */
+#define TARGET_BIG_SWITCH (target_flags & MASK_BIG_SWITCH)
+
+/* General debug flag */
+#define TARGET_DEBUG (target_flags & MASK_DEBUG)
+
+/* Macro to define tables used to set the flags.
+ This is a list in braces of pairs in braces,
+ each pair being { "NAME", VALUE }
+ where VALUE is the bits to set or minus the bits to clear.
+ An empty string NAME is used to identify the default VALUE. */
+
+#define TARGET_SWITCHES \
+ {{ "ghs", MASK_GHS }, \
+ { "no-ghs", -MASK_GHS }, \
+ { "long-calls", MASK_LONG_CALLS }, \
+ { "no-long-calls", -MASK_LONG_CALLS }, \
+ { "ep", MASK_EP }, \
+ { "no-ep", -MASK_EP }, \
+ { "prolog-function", MASK_PROLOG_FUNCTION }, \
+ { "no-prolog-function", -MASK_PROLOG_FUNCTION }, \
+ { "space", MASK_EP | MASK_PROLOG_FUNCTION }, \
+ { "debug", MASK_DEBUG }, \
+ { "v850", MASK_V850 }, \
+ { "v850", -(MASK_V850 ^ MASK_CPU) }, \
+ { "big-switch", MASK_BIG_SWITCH }, \
+ EXTRA_SWITCHES \
+ { "", TARGET_DEFAULT}}
+
+#ifndef EXTRA_SWITCHES
+#define EXTRA_SWITCHES
+#endif
+
+#ifndef TARGET_DEFAULT
+#define TARGET_DEFAULT MASK_DEFAULT
+#endif
+
+/* Information about the various small memory areas. */
+struct small_memory_info {
+ char *name;
+ char *value;
+ long max;
+ long physical_max;
+};
+
+enum small_memory_type {
+ /* tiny data area, using EP as base register */
+ SMALL_MEMORY_TDA = 0,
+ /* small data area using dp as base register */
+ SMALL_MEMORY_SDA,
+ /* zero data area using r0 as base register */
+ SMALL_MEMORY_ZDA,
+ SMALL_MEMORY_max
+};
+
+extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
+
+/* 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.
+
+ Here is an example which defines `-mshort-data-NUMBER'. If the
+ given option is `-mshort-data-512', the variable `m88k_short_data'
+ will be set to the string `"512"'.
+
+ extern char *m88k_short_data;
+ #define TARGET_OPTIONS \
+ { { "short-data-", &m88k_short_data } } */
+
+#define TARGET_OPTIONS \
+{ \
+ { "tda=", &small_memory[ (int)SMALL_MEMORY_TDA ].value }, \
+ { "tda-", &small_memory[ (int)SMALL_MEMORY_TDA ].value }, \
+ { "sda=", &small_memory[ (int)SMALL_MEMORY_SDA ].value }, \
+ { "sda-", &small_memory[ (int)SMALL_MEMORY_SDA ].value }, \
+ { "zda=", &small_memory[ (int)SMALL_MEMORY_ZDA ].value }, \
+ { "zda-", &small_memory[ (int)SMALL_MEMORY_ZDA ].value }, \
+}
+
+/* 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 ()
+
+
+/* Show we can debug even without a frame pointer. */
+#define CAN_DEBUG_WITHOUT_FP
+
+/* Some machines may desire to change what optimizations are
+ performed for various optimization levels. This macro, if
+ defined, is executed once just after the optimization level is
+ determined and before the remainder of the command options have
+ been parsed. Values set in this macro are used as the default
+ values for the other command line options.
+
+ LEVEL is the optimization level specified; 2 if `-O2' is
+ specified, 1 if `-O' is specified, and 0 if neither is specified.
+
+ You should not use this macro to change options that are not
+ machine-specific. These should uniformly selected by the same
+ optimization level on all supported machines. Use this macro to
+ enable machine-specific optimizations.
+
+ *Do not examine `write_symbols' in this macro!* The debugging
+ options are not supposed to alter the generated code. */
+
+#define OPTIMIZATION_OPTIONS(LEVEL) \
+{ \
+ if (LEVEL) \
+ target_flags |= (MASK_EP | MASK_PROLOG_FUNCTION); \
+}
+
+
+/* Target machine storage layout */
+
+/* Define this if most significant bit is lowest numbered
+ in instructions that operate on numbered bit-fields.
+ This is not true on the NEC V850. */
+#define BITS_BIG_ENDIAN 0
+
+/* Define this if most significant byte of a word is the lowest numbered. */
+/* This is not true on the NEC V850. */
+#define BYTES_BIG_ENDIAN 0
+
+/* Define this if most significant word of a multiword number is lowest
+ numbered.
+ This is not true on the NEC V850. */
+#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 68000, 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
+
+/* 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.
+
+ Some simple experiments have shown that leaving UNSIGNEDP alone
+ generates the best overall code. */
+
+#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
+ if (GET_MODE_CLASS (MODE) == MODE_INT \
+ && GET_MODE_SIZE (MODE) < 4) \
+ { (MODE) = SImode; }
+
+/* Allocation boundary (in *bits*) for storing arguments in argument list. */
+#define PARM_BOUNDARY 32
+
+/* The stack goes in 32 bit lumps. */
+#define STACK_BOUNDARY 32
+
+/* Allocation boundary (in *bits*) for the code of a function.
+ 16 is the minimum boundary; 32 would give better performance. */
+#define FUNCTION_BOUNDARY 16
+
+/* No data type wants to be aligned rounder than this. */
+#define BIGGEST_ALIGNMENT 32
+
+/* Alignment of field after `int : 0' in a structure. */
+#define EMPTY_FIELD_BOUNDARY 32
+
+/* No structure field wants to be aligned rounder than this. */
+#define BIGGEST_FIELD_ALIGNMENT 32
+
+/* Define this if move instructions will actually fail to work
+ when given unaligned data. */
+#define STRICT_ALIGNMENT 1
+
+/* Define this as 1 if `char' should by default be signed; else as 0.
+
+ On the NEC V850, loads do sign extension, so make this default. */
+#define DEFAULT_SIGNED_CHAR 1
+
+/* 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
+
+/* Standard register usage. */
+
+/* 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. */
+
+#define FIRST_PSEUDO_REGISTER 34
+
+/* 1 for registers that have pervasive standard uses
+ and are not available for the register allocator. */
+
+#define FIXED_REGISTERS \
+ { 1, 1, 0, 1, 1, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 1, 0, \
+ 1, 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 \
+ { 1, 1, 0, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 1, 1, \
+ 1, 1}
+
+/* List the order in which to allocate registers. Each register must be
+ listed once, even those in FIXED_REGISTERS.
+
+ On the 850, we make the return registers first, then all of the volatile
+ registers, then the saved registers in reverse order to better save the
+ registers with an out of line function, and finally the fixed
+ registers. */
+
+#define REG_ALLOC_ORDER \
+{ \
+ 10, 11, /* return registers */ \
+ 12, 13, 14, 15, 16, 17, 18, 19, /* scratch registers */ \
+ 6, 7, 8, 9, 31, /* argument registers */ \
+ 29, 28, 27, 26, 25, 24, 23, 22, /* saved registers */ \
+ 21, 20, 2, \
+ 0, 1, 3, 4, 5, 30, 32, 33 /* fixed registers */ \
+}
+
+/* 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. */
+
+#define HARD_REGNO_NREGS(REGNO, MODE) \
+ ((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. */
+
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+ ((((REGNO) & 1) == 0) || (GET_MODE_SIZE (MODE) <= 4))
+
+/* 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 || GET_MODE_SIZE (MODE1) <= 4 && GET_MODE_SIZE (MODE2) <= 4)
+
+
+/* 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. */
+
+enum reg_class {
+ NO_REGS, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
+};
+
+#define N_REG_CLASSES (int) LIM_REG_CLASSES
+
+/* Give names of register classes as strings for dump file. */
+
+#define REG_CLASS_NAMES \
+{ "NO_REGS", "GENERAL_REGS", "ALL_REGS", "LIM_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 \
+{ 0x00000000, /* No regs */ \
+ 0xffffffff, /* GENERAL_REGS */ \
+ 0xffffffff, /* ALL_REGS */ \
+}
+
+/* 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) GENERAL_REGS
+
+/* The class value for index registers, and the one for base regs. */
+
+#define INDEX_REG_CLASS NO_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) (NO_REGS)
+
+/* 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_BASE_P(regno) \
+ ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
+
+#define REGNO_OK_FOR_INDEX_P(regno) 0
+
+/* 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. */
+
+#define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS)
+
+/* Return the maximum number of consecutive registers
+ needed to represent mode MODE in a register of class CLASS. */
+
+#define CLASS_MAX_NREGS(CLASS, MODE) \
+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* The letters I, J, K, L, M, N, O, P 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. */
+
+#define INT_7_BITS(VALUE) ((unsigned) (VALUE) + 0x40 < 0x80)
+#define INT_8_BITS(VALUE) ((unsigned) (VALUE) + 0x80 < 0x100)
+/* zero */
+#define CONST_OK_FOR_I(VALUE) ((VALUE) == 0)
+/* 5 bit signed immediate */
+#define CONST_OK_FOR_J(VALUE) ((unsigned) (VALUE) + 0x10 < 0x20)
+/* 16 bit signed immediate */
+#define CONST_OK_FOR_K(VALUE) ((unsigned) (VALUE) + 0x8000 < 0x10000)
+/* valid constant for movhi instruction. */
+#define CONST_OK_FOR_L(VALUE) \
+ (((unsigned) ((int) (VALUE) >> 16) + 0x8000 < 0x10000) \
+ && CONST_OK_FOR_I ((VALUE & 0xffff)))
+/* 16 bit unsigned immediate */
+#define CONST_OK_FOR_M(VALUE) ((unsigned)(VALUE) < 0x10000)
+/* 5 bit unsigned immediate in shift instructions */
+#define CONST_OK_FOR_N(VALUE) ((unsigned) (VALUE) <= 31)
+
+#define CONST_OK_FOR_O(VALUE) 0
+#define CONST_OK_FOR_P(VALUE) 0
+
+
+#define CONST_OK_FOR_LETTER_P(VALUE, C) \
+ ((C) == 'I' ? CONST_OK_FOR_I (VALUE) : \
+ (C) == 'J' ? CONST_OK_FOR_J (VALUE) : \
+ (C) == 'K' ? CONST_OK_FOR_K (VALUE) : \
+ (C) == 'L' ? CONST_OK_FOR_L (VALUE) : \
+ (C) == 'M' ? CONST_OK_FOR_M (VALUE) : \
+ (C) == 'N' ? CONST_OK_FOR_N (VALUE) : \
+ (C) == 'O' ? CONST_OK_FOR_O (VALUE) : \
+ (C) == 'P' ? CONST_OK_FOR_P (VALUE) : \
+ 0)
+
+/* Similar, but for floating constants, and defining letters G and H.
+ Here VALUE is the CONST_DOUBLE rtx itself.
+
+ `G' is a zero of some form. */
+
+#define CONST_DOUBLE_OK_FOR_G(VALUE) \
+ ((GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
+ && (VALUE) == CONST0_RTX (GET_MODE (VALUE))) \
+ || (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_INT \
+ && CONST_DOUBLE_LOW (VALUE) == 0 \
+ && CONST_DOUBLE_HIGH (VALUE) == 0))
+
+#define CONST_DOUBLE_OK_FOR_H(VALUE) 0
+
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
+ ((C) == 'G' ? CONST_DOUBLE_OK_FOR_G (VALUE) \
+ : (C) == 'H' ? CONST_DOUBLE_OK_FOR_H (VALUE) \
+ : 0)
+
+
+/* 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
+
+/* Offset of first parameter from the argument pointer register value. */
+/* Is equal to the size of the saved fp + pc, even if an fp isn't
+ saved since the value is used before we know. */
+
+#define FIRST_PARM_OFFSET(FNDECL) 0
+
+/* Specify the registers used for certain standard purposes.
+ The values of these macros are register numbers. */
+
+/* Register to use for pushing function arguments. */
+#define STACK_POINTER_REGNUM 3
+
+/* Base register for access to local variables of the function. */
+#define FRAME_POINTER_REGNUM 32
+
+/* On some machines the offset between the frame pointer and starting
+ offset of the automatic variables is not known until after register
+ allocation has been done (for example, because the saved registers
+ are between these two locations). On those machines, define
+ `FRAME_POINTER_REGNUM' the number of a special, fixed register to
+ be used internally until the offset is known, and define
+ `HARD_FRAME_POINTER_REGNUM' to be actual the hard register number
+ used for the frame pointer.
+
+ You should define this macro only in the very rare circumstances
+ when it is not possible to calculate the offset between the frame
+ pointer and the automatic variables until after register
+ allocation has been completed. When this macro is defined, you
+ must also indicate in your definition of `ELIMINABLE_REGS' how to
+ eliminate `FRAME_POINTER_REGNUM' into either
+ `HARD_FRAME_POINTER_REGNUM' or `STACK_POINTER_REGNUM'.
+
+ Do not define this macro if it would be the same as
+ `FRAME_POINTER_REGNUM'. */
+#define HARD_FRAME_POINTER_REGNUM 29
+
+/* Base register for access to arguments of the function. */
+#define ARG_POINTER_REGNUM 33
+
+/* Register in which static-chain is passed to a function. */
+#define STATIC_CHAIN_REGNUM 5
+
+/* 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
+
+/* If defined, this macro specifies a table of register pairs used to
+ eliminate unneeded registers that point into the stack frame. If
+ it is not defined, the only elimination attempted by the compiler
+ is to replace references to the frame pointer with references to
+ the stack pointer.
+
+ The definition of this macro is a list of structure
+ initializations, each of which specifies an original and
+ replacement register.
+
+ On some machines, the position of the argument pointer is not
+ known until the compilation is completed. In such a case, a
+ separate hard register must be used for the argument pointer.
+ This register can be eliminated by replacing it with either the
+ frame pointer or the argument pointer, depending on whether or not
+ the frame pointer has been eliminated.
+
+ In this case, you might specify:
+ #define ELIMINABLE_REGS \
+ {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
+ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
+
+ Note that the elimination of the argument pointer with the stack
+ pointer is specified first since that is the preferred elimination. */
+
+#define ELIMINABLE_REGS \
+{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
+ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }} \
+
+/* A C expression that returns non-zero if the compiler is allowed to
+ try to replace register number FROM-REG with register number
+ TO-REG. This macro need only be defined if `ELIMINABLE_REGS' is
+ defined, and will usually be the constant 1, since most of the
+ cases preventing register elimination are things that the compiler
+ already knows about. */
+
+#define CAN_ELIMINATE(FROM, TO) \
+ ((TO) == STACK_POINTER_REGNUM ? ! frame_pointer_needed : 1)
+
+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It
+ specifies the initial difference between the specified pair of
+ registers. This macro must be defined if `ELIMINABLE_REGS' is
+ defined. */
+
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+{ \
+ if ((FROM) == FRAME_POINTER_REGNUM) \
+ (OFFSET) = get_frame_size () + current_function_outgoing_args_size; \
+ else if ((FROM) == ARG_POINTER_REGNUM) \
+ (OFFSET) = compute_frame_size (get_frame_size (), (long *)0); \
+ else \
+ abort (); \
+}
+
+/* A guess for the V850. */
+#define PROMOTE_PROTOTYPES 1
+
+/* Keep the stack pointer constant throughout the function. */
+#define ACCUMULATE_OUTGOING_ARGS
+
+/* 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. */
+
+#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
+
+
+/* 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. */
+
+#define CUMULATIVE_ARGS struct cum_arg
+struct cum_arg { int nbytes; };
+
+/* 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();
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
+ function_arg (&CUM, MODE, TYPE, NAMED)
+
+#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
+ function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
+
+/* 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,INDIRECT) \
+ ((CUM).nbytes = 0)
+
+/* 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) \
+ ((CUM).nbytes += ((MODE) != BLKmode \
+ ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD \
+ : (int_size_in_bytes (TYPE) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD))
+
+/* When a parameter is passed in a register, stack space is still
+ allocated for it. */
+#define REG_PARM_STACK_SPACE(DECL) (!TARGET_GHS ? 16 : 0)
+
+/* Define this if the above stack space is to be considered part of the
+ space allocated by the caller. */
+#define OUTGOING_REG_PARM_STACK_SPACE
+
+extern int current_function_anonymous_args;
+/* Do any setup necessary for varargs/stdargs functions. */
+#define SETUP_INCOMING_VARARGS(CUM, MODE, TYPE, PAS, SECOND) \
+ current_function_anonymous_args = (!TARGET_GHS ? 1 : 0);
+
+#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
+ ((TYPE) && int_size_in_bytes (TYPE) > 8)
+
+#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
+ ((TYPE) && int_size_in_bytes (TYPE) > 8)
+
+/* 1 if N is a possible register number for function argument passing. */
+
+#define FUNCTION_ARG_REGNO_P(N) (N >= 6 && N <= 9)
+
+/* 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), 10)
+
+/* 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, 10)
+
+/* 1 if N is a possible register number for a function value. */
+
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == 10)
+
+/* Return values > 8 bytes in length in memory. */
+#define DEFAULT_PCC_STRUCT_RETURN 0
+#define RETURN_IN_MEMORY(TYPE) \
+ (int_size_in_bytes (TYPE) > 8 || TYPE_MODE (TYPE) == BLKmode)
+
+/* Register in which address to store a structure value
+ is passed to a function. On the V850 it's passed as
+ the first parameter. */
+
+#define STRUCT_VALUE 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. */
+
+#define EXIT_IGNORE_STACK 1
+
+/* Output assembler code to FILE to increment profiler label # LABELNO
+ for profiling a function entry. */
+
+#define FUNCTION_PROFILER(FILE, LABELNO) ;
+
+#define TRAMPOLINE_TEMPLATE(FILE) \
+ do { \
+ fprintf (FILE, "\tjarl .+4,r12\n"); \
+ fprintf (FILE, "\tld.w 12[r12],r5\n"); \
+ fprintf (FILE, "\tld.w 16[r12],r12\n"); \
+ fprintf (FILE, "\tjmp [r12]\n"); \
+ fprintf (FILE, "\tnop\n"); \
+ fprintf (FILE, "\t.long 0\n"); \
+ fprintf (FILE, "\t.long 0\n"); \
+ } while (0)
+
+/* Length in units of the trampoline for entering a nested function. */
+
+#define TRAMPOLINE_SIZE 24
+
+/* 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), 16)), \
+ (CXT)); \
+ emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 20)), \
+ (FNADDR)); \
+}
+
+/* Addressing modes, and classification of registers for them. */
+
+
+/* 1 if X is an rtx for a constant that is a valid address. */
+
+/* ??? This seems too exclusive. May get better code by accepting more
+ possibilities here, in particular, should accept ZDA_NAME SYMBOL_REFs. */
+
+#define CONSTANT_ADDRESS_P(X) \
+ (GET_CODE (X) == CONST_INT \
+ && CONST_OK_FOR_K (INTVAL (X)))
+
+/* Maximum number of registers that can appear in a valid memory address. */
+
+#define MAX_REGS_PER_ADDRESS 1
+
+/* 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. */
+
+#ifndef REG_OK_STRICT
+
+/* Nonzero if X is a hard reg that can be used as an index
+ or if it is a pseudo reg. */
+#define REG_OK_FOR_INDEX_P(X) 0
+/* Nonzero if X is a hard reg that can be used as a base reg
+ or if it is a pseudo reg. */
+#define REG_OK_FOR_BASE_P(X) 1
+#define REG_OK_FOR_INDEX_P_STRICT(X) 0
+#define REG_OK_FOR_BASE_P_STRICT(X) REGNO_OK_FOR_BASE_P (REGNO (X))
+#define STRICT 0
+
+#else
+
+/* Nonzero if X is a hard reg that can be used as an index. */
+#define REG_OK_FOR_INDEX_P(X) 0
+/* Nonzero if X is a hard reg that can be used as a base reg. */
+#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
+#define STRICT 1
+
+#endif
+
+/* A C expression that defines the optional machine-dependent
+ constraint letters that can be used to segregate specific types of
+ operands, usually memory references, for the target machine.
+ Normally this macro will not be defined. If it is required for a
+ particular target machine, it should return 1 if VALUE corresponds
+ to the operand type represented by the constraint letter C. If C
+ is not defined as an extra constraint, the value returned should
+ be 0 regardless of VALUE.
+
+ For example, on the ROMP, load instructions cannot have their
+ output in r0 if the memory reference contains a symbolic address.
+ Constraint letter `Q' is defined as representing a memory address
+ that does *not* contain a symbolic address. An alternative is
+ specified with a `Q' constraint on the input and `r' on the
+ output. The next alternative specifies `m' on the input and a
+ register class that does not include r0 on the output. */
+
+#define EXTRA_CONSTRAINT(OP, C) \
+ ((C) == 'Q' ? ep_memory_operand (OP, GET_MODE (OP)) \
+ : (C) == 'R' ? special_symbolref_operand (OP, VOIDmode) \
+ : (C) == 'S' ? (GET_CODE (OP) == SYMBOL_REF && ! ZDA_NAME_P (XSTR (OP, 0))) \
+ : (C) == 'T' ? 0 \
+ : (C) == 'U' ? ((GET_CODE (OP) == SYMBOL_REF && ZDA_NAME_P (XSTR (OP, 0))) \
+ || (GET_CODE (OP) == CONST \
+ && GET_CODE (XEXP (OP, 0)) == PLUS \
+ && GET_CODE (XEXP (XEXP (OP, 0), 0)) == SYMBOL_REF \
+ && ZDA_NAME_P (XSTR (XEXP (XEXP (OP, 0), 0), 0)))) \
+ : 0)
+
+/* 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 actually
+ machine-independent. */
+
+/* Accept either REG or SUBREG where a register is valid. */
+
+#define RTX_OK_FOR_BASE_P(X) \
+ ((REG_P (X) && REG_OK_FOR_BASE_P (X)) \
+ || (GET_CODE (X) == SUBREG && REG_P (SUBREG_REG (X)) \
+ && REG_OK_FOR_BASE_P (SUBREG_REG (X))))
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+do { \
+ if (RTX_OK_FOR_BASE_P (X)) goto ADDR; \
+ if (CONSTANT_ADDRESS_P (X) \
+ && (MODE == QImode || INTVAL (X) % 2 == 0)) \
+ goto ADDR; \
+ if (GET_CODE (X) == LO_SUM \
+ && GET_CODE (XEXP (X, 0)) == REG \
+ && REG_OK_FOR_BASE_P (XEXP (X, 0)) \
+ && CONSTANT_P (XEXP (X, 1)) \
+ && (GET_CODE (XEXP (X, 1)) != CONST_INT \
+ || ((MODE == QImode || INTVAL (XEXP (X, 1)) % 2 == 0) \
+ && CONST_OK_FOR_K (INTVAL (XEXP (X, 1))))) \
+ && GET_MODE_SIZE (MODE) <= GET_MODE_SIZE (word_mode)) \
+ goto ADDR; \
+ if (special_symbolref_operand (X, MODE) \
+ && (GET_MODE_SIZE (MODE) <= GET_MODE_SIZE (word_mode))) \
+ goto ADDR; \
+ if (GET_CODE (X) == PLUS \
+ && CONSTANT_ADDRESS_P (XEXP (X, 1)) \
+ && (MODE == QImode || INTVAL (XEXP (X, 1)) % 2 == 0) \
+ && RTX_OK_FOR_BASE_P (XEXP (X, 0))) goto ADDR; \
+} while (0)
+
+
+/* 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. */
+
+#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) {}
+
+/* Go to LABEL if ADDR (a legitimate address expression)
+ has an effect that depends on the machine mode it is used for. */
+
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) {}
+
+/* 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) \
+ (GET_CODE (X) == CONST_DOUBLE \
+ || !(GET_CODE (X) == CONST \
+ && GET_CODE (XEXP (X, 0)) == PLUS \
+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
+ && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
+ && ! CONST_OK_FOR_K (INTVAL (XEXP (XEXP (X, 0), 1)))))
+
+/* In rare cases, correct code generation requires extra machine
+ dependent processing between the second jump optimization pass and
+ delayed branch scheduling. On those machines, define this macro
+ as a C statement to act on the code starting at INSN. */
+
+#define MACHINE_DEPENDENT_REORG(INSN) v850_reorg (INSN)
+
+
+/* Tell final.c how to eliminate redundant test instructions. */
+
+/* Here we define machine-dependent flags and fields in cc_status
+ (see `conditions.h'). No extra ones are needed for the vax. */
+
+/* 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 CC_OVERFLOW_UNUSABLE 0x200
+#define CC_NO_CARRY CC_NO_OVERFLOW
+#define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc(EXP, INSN)
+
+/* A part of a C `switch' statement that describes the relative costs
+ of constant RTL expressions. It must contain `case' labels for
+ expression codes `const_int', `const', `symbol_ref', `label_ref'
+ and `const_double'. Each case must ultimately reach a `return'
+ statement to return the relative cost of the use of that kind of
+ constant value in an expression. The cost may depend on the
+ precise value of the constant, which is available for examination
+ in X, and the rtx code of the expression in which it is contained,
+ found in OUTER_CODE.
+
+ CODE is the expression code--redundant, since it can be obtained
+ with `GET_CODE (X)'. */
+
+#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
+ case CONST_INT: \
+ case CONST_DOUBLE: \
+ case CONST: \
+ case SYMBOL_REF: \
+ case LABEL_REF: \
+ { \
+ int _zxy = const_costs(RTX, CODE); \
+ return (_zxy) ? COSTS_N_INSNS (_zxy) : 0; \
+ }
+
+/* A crude cut at RTX_COSTS for the V850. */
+
+/* Provide the costs of a rtl expression. This is in the body of a
+ switch on CODE.
+
+ There aren't DImode MOD, DIV or MULT operations, so call them
+ very expensive. Everything else is pretty much a constant cost. */
+
+#define RTX_COSTS(RTX,CODE,OUTER_CODE) \
+ case MOD: \
+ case DIV: \
+ return 60; \
+ case MULT: \
+ return 20;
+
+/* All addressing modes have the same cost on the V850 series. */
+#define ADDRESS_COST(ADDR) 1
+
+/* Nonzero if access to memory by bytes or half words is no faster
+ than accessing full words. */
+#define SLOW_BYTE_ACCESS 1
+
+/* Define this if zero-extension is slow (more than one real instruction). */
+#define SLOW_ZERO_EXTEND
+
+/* According expr.c, a value of around 6 should minimize code size, and
+ for the V850 series, that's our primary concern. */
+#define MOVE_RATIO 6
+
+/* Indirect calls are expensive, never turn a direct call
+ into an indirect call. */
+#define NO_FUNCTION_CSE
+
+/* 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_tdata, in_sdata, in_zdata, in_const, in_ctors, in_dtors
+
+/* One or more functions to be defined in `varasm.c'. These
+ functions should do jobs analogous to those of `text_section' and
+ `data_section', for your additional sections. Do not define this
+ macro if you do not define `EXTRA_SECTIONS'. */
+#undef EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS \
+CONST_SECTION_FUNCTION \
+CTORS_SECTION_FUNCTION \
+DTORS_SECTION_FUNCTION \
+ \
+void \
+sdata_section () \
+{ \
+ if (in_section != in_sdata) \
+ { \
+ fprintf (asm_out_file, "%s\n", SDATA_SECTION_ASM_OP); \
+ in_section = in_sdata; \
+ } \
+} \
+ \
+void \
+tdata_section () \
+{ \
+ if (in_section != in_tdata) \
+ { \
+ fprintf (asm_out_file, "%s\n", TDATA_SECTION_ASM_OP); \
+ in_section = in_tdata; \
+ } \
+} \
+ \
+void \
+zdata_section () \
+{ \
+ if (in_section != in_zdata) \
+ { \
+ fprintf (asm_out_file, "%s\n", ZDATA_SECTION_ASM_OP); \
+ in_section = in_zdata; \
+ } \
+}
+
+#define TEXT_SECTION_ASM_OP "\t.section .text"
+#define DATA_SECTION_ASM_OP "\t.section .data"
+#define BSS_SECTION_ASM_OP "\t.section .bss"
+#define SDATA_SECTION_ASM_OP "\t.section .sdata,\"aw\""
+#define SBSS_SECTION_ASM_OP "\t.section .sbss,\"aw\""
+#define ZDATA_SECTION_ASM_OP "\t.section .zdata,\"aw\""
+#define ZBSS_SECTION_ASM_OP "\t.section .zbss,\"aw\""
+#define TDATA_SECTION_ASM_OP "\t.section .tdata,\"aw\""
+
+/* A C statement or statements to switch to the appropriate section
+ for output of EXP. You can assume that EXP is either a `VAR_DECL'
+ node or a constant of some sort. RELOC indicates whether the
+ initial value of EXP requires link-time relocations. Select the
+ section by calling `text_section' or one of the alternatives for
+ other sections.
+
+ Do not define this macro if you put all read-only variables and
+ constants in the read-only data section (usually the text section). */
+#undef SELECT_SECTION
+#define SELECT_SECTION(EXP, RELOC) \
+do { \
+ if (TREE_CODE (EXP) == VAR_DECL) \
+ { \
+ if (!TREE_READONLY (EXP) || TREE_SIDE_EFFECTS (EXP) \
+ || !DECL_INITIAL (EXP) \
+ || (DECL_INITIAL (EXP) != error_mark_node \
+ && !TREE_CONSTANT (DECL_INITIAL (EXP)))) \
+ data_section (); \
+ else \
+ const_section (); \
+ } \
+ else if (TREE_CODE (EXP) == STRING_CST) \
+ { \
+ if (! flag_writable_strings) \
+ const_section (); \
+ else \
+ data_section (); \
+ } \
+ \
+ else \
+ const_section (); \
+ \
+} while (0)
+
+/* A C statement or statements to switch to the appropriate section
+ for output of RTX in mode MODE. You can assume that RTX is some
+ kind of constant in RTL. The argument MODE is redundant except in
+ the case of a `const_int' rtx. Select the section by calling
+ `text_section' or one of the alternatives for other sections.
+
+ Do not define this macro if you put all constants in the read-only
+ data section. */
+/* #define SELECT_RTX_SECTION(MODE, RTX) */
+
+/* Output at beginning/end of assembler file. */
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) asm_file_start(FILE)
+
+#define ASM_COMMENT_START "#"
+
+/* 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"
+
+/* This is how to output an assembler line defining a `double' constant.
+ It is .double or .float, depending. */
+
+#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
+do { char dstr[30]; \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", dstr); \
+ fprintf (FILE, "\t.double %s\n", dstr); \
+ } while (0)
+
+
+/* This is how to output an assembler line defining a `float' constant. */
+#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
+do { char dstr[30]; \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", dstr); \
+ fprintf (FILE, "\t.float %s\n", dstr); \
+ } while (0)
+
+/* This is how to output an assembler line defining an `int' constant. */
+
+#define ASM_OUTPUT_INT(FILE, VALUE) \
+( fprintf (FILE, "\t.long "), \
+ output_addr_const (FILE, (VALUE)), \
+ fprintf (FILE, "\n"))
+
+/* Likewise for `char' and `short' constants. */
+
+#define ASM_OUTPUT_SHORT(FILE, VALUE) \
+( fprintf (FILE, "\t.hword "), \
+ output_addr_const (FILE, (VALUE)), \
+ fprintf (FILE, "\n"))
+
+#define ASM_OUTPUT_CHAR(FILE, VALUE) \
+( fprintf (FILE, "\t.byte "), \
+ output_addr_const (FILE, (VALUE)), \
+ fprintf (FILE, "\n"))
+
+/* This is how to output an assembler line for a numeric constant byte. */
+#define ASM_OUTPUT_BYTE(FILE, VALUE) \
+ fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
+
+/* Define the parentheses used to group arithmetic operations
+ in assembler code. */
+
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
+
+/* This says how to output the assembler to define a global
+ uninitialized but not common symbol.
+ Try to use asm_output_bss to implement this macro. */
+
+#define ASM_OUTPUT_BSS(FILE, DECL, NAME, SIZE, ROUNDED) \
+ asm_output_bss ((FILE), (DECL), (NAME), (SIZE), (ROUNDED))
+
+/* 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) \
+ do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
+
+/* 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) \
+ do { fputs ("\t.global ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
+
+/* This is how to output a reference to a user-level label named NAME.
+ `assemble_name' uses this. */
+
+#undef ASM_OUTPUT_LABELREF
+#define ASM_OUTPUT_LABELREF(FILE, NAME) \
+ do { \
+ char* real_name; \
+ STRIP_NAME_ENCODING (real_name, (NAME)); \
+ fprintf (FILE, "_%s", real_name); \
+ } 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 we tell the assembler that two symbols have the same value. */
+
+#define ASM_OUTPUT_DEF(FILE,NAME1,NAME2) \
+ do { assemble_name(FILE, NAME1); \
+ fputs(" = ", FILE); \
+ assemble_name(FILE, NAME2); \
+ fputc('\n', FILE); } while (0)
+
+
+/* How to refer to registers in assembler output.
+ This sequence is indexed by compiler's hard-register-number (see above). */
+
+#define REGISTER_NAMES \
+{ "r0", "r1", "r2", "sp", "gp", "r5", "r6" , "r7", \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
+ "r24", "r25", "r26", "r27", "r28", "r29", "ep", "r31", \
+ ".fp", ".ap"}
+
+#define ADDITIONAL_REGISTER_NAMES \
+{ { "zero", 0 }, \
+ { "hp", 2 }, \
+ { "r3", 3 }, \
+ { "r4", 4 }, \
+ { "tp", 5 }, \
+ { "fp", 29 }, \
+ { "r30", 30 }, \
+ { "lp", 31} }
+
+/* Print an instruction operand X on file FILE.
+ look in v850.c for details */
+
+#define PRINT_OPERAND(FILE, X, CODE) print_operand(FILE,X,CODE)
+
+#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
+ ((CODE) == '.')
+
+/* Print a memory operand whose address is X, on file FILE.
+ This uses a function in output-vax.c. */
+
+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
+
+#define ASM_OUTPUT_REG_PUSH(FILE,REGNO)
+#define ASM_OUTPUT_REG_POP(FILE,REGNO)
+
+/* This is how to output an element of a case-vector that is absolute. */
+
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
+ asm_fprintf (FILE, "\t%s .L%d\n", \
+ (TARGET_BIG_SWITCH ? ".long" : ".short"), VALUE)
+
+/* This is how to output an element of a case-vector that is relative. */
+
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
+ fprintf (FILE, "\t%s .L%d-.L%d\n", \
+ (TARGET_BIG_SWITCH ? ".long" : ".short"), \
+ VALUE, REL)
+
+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
+ if ((LOG) != 0) \
+ fprintf (FILE, "\t.align %d\n", (LOG))
+
+/* We don't have to worry about dbx compatibility for the v850. */
+#define DEFAULT_GDB_EXTENSIONS 1
+
+/* Use stabs debugging info by default. */
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+#define DBX_REGISTER_NUMBER(REGNO) REGNO
+
+/* Define to use software floating point emulator for REAL_ARITHMETIC and
+ decimal <-> binary conversion. */
+#define REAL_ARITHMETIC
+
+/* Specify the machine mode that this machine uses
+ for the index in the tablejump instruction. */
+#define CASE_VECTOR_MODE (TARGET_BIG_SWITCH ? SImode : HImode)
+
+/* Define this if the case instruction drops through after the table
+ when the index is out of range. Don't define it if the case insn
+ jumps to the default label instead. */
+/* #define CASE_DROPS_THROUGH */
+
+/* We must use a PC relative entry for small tables. It would be more
+ efficient to use an absolute entry for big tables, but this is not
+ a runtime choice yet. */
+#define CASE_VECTOR_PC_RELATIVE
+
+/* The switch instruction requires that the jump table immediately follow
+ it. */
+#define JUMP_TABLES_IN_TEXT_SECTION
+
+/* svr4.h defines this assuming that 4 byte alignment is required. */
+#undef ASM_OUTPUT_BEFORE_CASE_LABEL
+#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
+ ASM_OUTPUT_ALIGN ((FILE), (TARGET_BIG_SWITCH ? 2 : 1));
+
+#define WORD_REGISTER_OPERATIONS
+
+/* Byte and short loads sign extend the value to a word. */
+#define LOAD_EXTEND_OP(MODE) SIGN_EXTEND
+
+/* Specify the tree operation to be used to convert reals to integers. */
+#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
+
+/* This flag, if defined, says the same insns that convert to a signed fixnum
+ also convert validly to an unsigned one. */
+#define FIXUNS_TRUNC_LIKE_FIX_TRUNC
+
+/* This is the kind of divide that is easiest to do in the general case. */
+#define EASY_DIV_EXPR TRUNC_DIV_EXPR
+
+/* Max number of bytes we can move from memory to memory
+ in one reasonably fast instruction. */
+#define MOVE_MAX 4
+
+/* Define if shifts truncate the shift count
+ which implies one can omit a sign-extension or zero-extension
+ of a shift count. */
+#define SHIFT_COUNT_TRUNCATED 1
+
+/* 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
+
+#define STORE_FLAG_VALUE 1
+
+/* 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
+
+/* 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, IDENTIFIER, ARGS) \
+v850_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
+
+/* Tell compiler we have {ZDA,TDA,SDA} small data regions */
+#define HAVE_ZDA 1
+#define HAVE_SDA 1
+#define HAVE_TDA 1
+
+/* Tell compiler we want to support GHS pragmas */
+#define HANDLE_GHS_PRAGMA
+
+/* The assembler op to to start the file. */
+
+#define FILE_ASM_OP "\t.file\n"
+
+/* Enable the register move pass to improve code. */
+#define ENABLE_REGMOVE_PASS
+
+
+/* Implement ZDA, TDA, and SDA */
+
+#define EP_REGNUM 30 /* ep register number */
+
+#define ENCODE_SECTION_INFO(DECL) \
+do { \
+ if ((TREE_STATIC (DECL) || DECL_EXTERNAL (DECL)) \
+ && TREE_CODE (DECL) == VAR_DECL) \
+ v850_encode_data_area (DECL); \
+} while (0)
+
+#define ZDA_NAME_FLAG_CHAR '@'
+#define TDA_NAME_FLAG_CHAR '%'
+#define SDA_NAME_FLAG_CHAR '&'
+
+#define ZDA_NAME_P(NAME) (*(NAME) == ZDA_NAME_FLAG_CHAR)
+#define TDA_NAME_P(NAME) (*(NAME) == TDA_NAME_FLAG_CHAR)
+#define SDA_NAME_P(NAME) (*(NAME) == SDA_NAME_FLAG_CHAR)
+
+#define ENCODED_NAME_P(SYMBOL_NAME) \
+ (ZDA_NAME_P (SYMBOL_NAME) \
+ || TDA_NAME_P (SYMBOL_NAME) \
+ || SDA_NAME_P (SYMBOL_NAME))
+
+#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
+ (VAR) = (SYMBOL_NAME) + (ENCODED_NAME_P (SYMBOL_NAME) || *(SYMBOL_NAME) == '*')
+
+/* Define this if you have defined special-purpose predicates in the
+ file `MACHINE.c'. This macro is called within an initializer of an
+ array of structures. The first field in the structure is the name
+ of a predicate and the second field is an array of rtl codes. For
+ each predicate, list all rtl codes that can be in expressions
+ matched by the predicate. The list should have a trailing comma. */
+
+#define PREDICATE_CODES \
+{ "ep_memory_operand", { MEM }}, \
+{ "reg_or_0_operand", { REG, SUBREG, CONST_INT, CONST_DOUBLE }}, \
+{ "reg_or_int5_operand", { REG, SUBREG, CONST_INT }}, \
+{ "call_address_operand", { REG, SYMBOL_REF }}, \
+{ "movsi_source_operand", { LABEL_REF, SYMBOL_REF, CONST_INT, \
+ CONST_DOUBLE, CONST, HIGH, MEM, \
+ REG, SUBREG }}, \
+{ "special_symbolref_operand", { SYMBOL_REF }}, \
+{ "power_of_two_operand", { CONST_INT }}, \
+{ "pattern_is_ok_for_prologue", { PARALLEL }}, \
+{ "pattern_is_ok_for_epilogue", { PARALLEL }}, \
+{ "register_is_ok_for_epilogue",{ REG }}, \
+{ "not_power_of_two_operand", { CONST_INT }},
+
+extern void override_options ();
+extern void asm_file_start ();
+extern int function_arg_partial_nregs ();
+extern int const_costs ();
+extern void print_operand ();
+extern void print_operand_address ();
+extern char *output_move_double ();
+extern char *output_move_single ();
+extern int ep_operand ();
+extern int reg_or_0_operand ();
+extern int reg_or_int5_operand ();
+extern int call_address_operand ();
+extern int movsi_source_operand ();
+extern int power_of_two_operand ();
+extern int not_power_of_two_operand ();
+extern void v850_reorg ();
+extern int compute_register_save_size ();
+extern int compute_frame_size ();
+extern void expand_prologue ();
+extern void expand_epilogue ();
+extern void notice_update_cc ();
+extern int v850_valid_machine_decl_attribute ();
+extern int v850_interrupt_function_p ();
+
+extern int pattern_is_ok_for_prologue();
+extern int pattern_is_ok_for_epilogue();
+extern int register_is_ok_for_epilogue ();
+extern char *construct_save_jarl ();
+extern char *construct_restore_jr ();
+
+
diff --git a/gnu/usr.bin/gcc/config/v850/v850.md b/gnu/usr.bin/gcc/config/v850/v850.md
new file mode 100644
index 00000000000..0ba10ca0cc0
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/v850/v850.md
@@ -0,0 +1,1273 @@
+;; GCC machine description for NEC V850
+;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+
+;; Contributed by Jeff Law (law@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.
+
+;; 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.
+
+;; The V851 manual states that the instruction address space is 16M;
+;; the various branch/call instructions only have a 22bit offset (4M range).
+;;
+;; One day we'll probably need to handle calls to targets more than 4M
+;; away.
+
+;; The size of instructions in bytes.
+
+(define_attr "length" ""
+ (const_int 200))
+
+;; Types of instructions (for scheduling purposes).
+
+(define_attr "type" "load,mult,other"
+ (const_string "other"))
+
+;; Condition code settings.
+;; none - insn does not affect cc
+;; none_0hit - insn does not affect cc but it does modify operand 0
+;; This attribute is used to keep track of when operand 0 changes.
+;; See the description of NOTICE_UPDATE_CC for more info.
+;; set_znv - sets z,n,v to usable values; c is unknown.
+;; set_zn - sets z,n to usable values; v,c is unknown.
+;; compare - compare instruction
+;; clobber - value of cc is unknown
+(define_attr "cc" "none,none_0hit,set_zn,set_znv,compare,clobber"
+ (const_string "clobber"))
+
+;; Function units for the V850. As best as I can tell, there's
+;; a traditional memory load/use stall as well as a stall if
+;; the result of a multiply is used too early.
+;;
+(define_function_unit "memory" 1 0 (eq_attr "type" "load") 2 0)
+(define_function_unit "mult" 1 0 (eq_attr "type" "mult") 2 0)
+
+
+;; ----------------------------------------------------------------------
+;; MOVE INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+;; movqi
+
+(define_expand "movqi"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (match_operand:QI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register or 0 */
+ if (!register_operand (operand0, QImode)
+ && !reg_or_0_operand (operand1, QImode))
+ operands[1] = copy_to_mode_reg (QImode, operand1);
+}")
+
+(define_insn "*movqi_internal"
+ [(set (match_operand:QI 0 "general_operand" "=r,r,r,Q,r,m,m")
+ (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
+ "register_operand (operands[0], QImode)
+ || reg_or_0_operand (operands[1], QImode)"
+ "* return output_move_single (operands);"
+ [(set_attr "length" "2,4,2,2,4,4,4")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
+ (set_attr "type" "other,other,load,other,load,other,other")])
+
+;; movhi
+
+(define_expand "movhi"
+ [(set (match_operand:HI 0 "general_operand" "")
+ (match_operand:HI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register or 0 */
+ if (!register_operand (operand0, HImode)
+ && !reg_or_0_operand (operand1, HImode))
+ operands[1] = copy_to_mode_reg (HImode, operand1);
+}")
+
+(define_insn "*movhi_internal"
+ [(set (match_operand:HI 0 "general_operand" "=r,r,r,Q,r,m,m")
+ (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
+ "register_operand (operands[0], HImode)
+ || reg_or_0_operand (operands[1], HImode)"
+ "* return output_move_single (operands);"
+ [(set_attr "length" "2,4,2,2,4,4,4")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
+ (set_attr "type" "other,other,load,other,load,other,other")])
+
+;; movsi and helpers
+
+(define_insn "*movsi_high"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (match_operand 1 "" "")))]
+ ""
+ "movhi hi(%1),%.,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")
+ (set_attr "type" "other")])
+
+(define_insn "*movsi_lo"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ ""
+ "movea lo(%2),%1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")
+ (set_attr "type" "other")])
+
+(define_expand "movsi"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (match_operand:SI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register or 0 */
+ if (!register_operand (operand0, SImode)
+ && !reg_or_0_operand (operand1, SImode))
+ operands[1] = copy_to_mode_reg (SImode, operand1);
+
+ /* Some constants, as well as symbolic operands
+ must be done with HIGH & LO_SUM patterns. */
+ if (CONSTANT_P (operands[1])
+ && GET_CODE (operands[1]) != HIGH
+ && !special_symbolref_operand (operands[1], VOIDmode)
+ && !(GET_CODE (operands[1]) == CONST_INT
+ && (CONST_OK_FOR_J (INTVAL (operands[1]))
+ || CONST_OK_FOR_K (INTVAL (operands[1]))
+ || CONST_OK_FOR_L (INTVAL (operands[1])))))
+ {
+ rtx high;
+ rtx temp;
+
+ if (reload_in_progress || reload_completed)
+ temp = operands[0];
+ else
+ temp = gen_reg_rtx (SImode);
+
+ emit_insn (gen_rtx (SET, SImode, temp,
+ gen_rtx (HIGH, SImode, operand1)));
+ emit_insn (gen_rtx (SET, SImode, operand0,
+ gen_rtx (LO_SUM, SImode, temp, operand1)));
+ DONE;
+ }
+}")
+
+(define_insn "*movsi_internal"
+ [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m")
+ (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
+ "register_operand (operands[0], SImode)
+ || reg_or_0_operand (operands[1], SImode)"
+ "* return output_move_single (operands);"
+ [(set_attr "length" "2,4,4,2,2,4,4,4,4")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
+ (set_attr "type" "other,other,other,load,other,load,other,other,other")])
+
+
+
+(define_expand "movdi"
+ [(set (match_operand:DI 0 "general_operand" "")
+ (match_operand:DI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register or 0 */
+ if (!register_operand (operand0, DImode)
+ && !reg_or_0_operand (operand1, DImode))
+ operands[1] = copy_to_mode_reg (DImode, operand1);
+}")
+
+(define_insn "*movdi_internal"
+ [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,m,r")
+ (match_operand:DI 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
+ "register_operand (operands[0], DImode)
+ || reg_or_0_operand (operands[1], DImode)"
+ "* return output_move_double (operands);"
+ [(set_attr "length" "4,8,8,16,8,8,8,16")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
+ (set_attr "type" "other,other,other,other,load,other,other,other")])
+
+(define_expand "movsf"
+ [(set (match_operand:SF 0 "general_operand" "")
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register or 0 */
+ if (!register_operand (operand0, SFmode)
+ && !reg_or_0_operand (operand1, SFmode))
+ operands[1] = copy_to_mode_reg (SFmode, operand1);
+}")
+
+(define_insn "*movsf_internal"
+ [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r")
+ (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
+ "register_operand (operands[0], SFmode)
+ || reg_or_0_operand (operands[1], SFmode)"
+ "* return output_move_single (operands);"
+ [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
+ (set_attr "type" "other,other,other,other,load,other,load,other,other,other")])
+
+(define_expand "movdf"
+ [(set (match_operand:DF 0 "general_operand" "")
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register or 0 */
+ if (!register_operand (operand0, DFmode)
+ && !reg_or_0_operand (operand1, DFmode))
+ operands[1] = copy_to_mode_reg (DFmode, operand1);
+}")
+
+(define_insn "*movdf_internal"
+ [(set (match_operand:DF 0 "general_operand" "=r,r,r,r,r,m,m,r")
+ (match_operand:DF 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
+ "register_operand (operands[0], DFmode)
+ || reg_or_0_operand (operands[1], DFmode)"
+ "* return output_move_double (operands);"
+ [(set_attr "length" "4,8,8,16,8,8,8,16")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
+ (set_attr "type" "other,other,other,other,load,other,other,other")])
+
+
+;; ----------------------------------------------------------------------
+;; TEST INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "*v850_tst1"
+ [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
+ (const_int 1)
+ (match_operand:QI 1 "const_int_operand" "n")))]
+ ""
+ "tst1 %1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; This replaces ld.b;sar;andi with tst1;setf nz.
+
+;; ??? The zero_extract sets the Z bit to the opposite of what one would
+;; expect. This perhaps should be wrapped in a (eq: X (const_int 0)).
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
+ (const_int 1)
+ (match_operand 2 "const_int_operand" "")))]
+ ""
+ [(set (cc0) (zero_extract:SI (match_dup 1)
+ (const_int 1)
+ (match_dup 2)))
+ (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
+
+(define_insn "tstsi"
+ [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
+ ""
+ "cmp %.,%0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "set_znv")])
+
+(define_insn "cmpsi"
+ [(set (cc0)
+ (compare (match_operand:SI 0 "register_operand" "r,r")
+ (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
+ ""
+ "@
+ cmp %1,%0
+ cmp %1,%0"
+ [(set_attr "length" "2,2")
+ (set_attr "cc" "compare")])
+
+;; ----------------------------------------------------------------------
+;; ADD INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "addsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
+ (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))]
+ ""
+ "@
+ add %2,%0
+ addi %2,%1,%0
+ addi %O2(%P2),%1,%0"
+ [(set_attr "length" "2,4,4")
+ (set_attr "cc" "set_zn,set_zn,set_zn")])
+
+;; ----------------------------------------------------------------------
+;; SUBTRACT INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "subsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (minus:SI (match_operand:SI 1 "register_operand" "0,r")
+ (match_operand:SI 2 "register_operand" "r,0")))]
+ ""
+ "@
+ sub %2,%0
+ subr %1,%0"
+ [(set_attr "length" "2,2")
+ (set_attr "cc" "set_zn")])
+
+(define_insn "negsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (neg:SI (match_operand:SI 1 "register_operand" "0")))]
+ ""
+ "subr %.,%0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "set_zn")])
+
+;; ----------------------------------------------------------------------
+;; MULTIPLY INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_expand "mulhisi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (mult:SI
+ (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
+ (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
+ ""
+ "")
+
+(define_insn "*mulhisi3_internal1"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI
+ (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
+ (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
+ ""
+ "mulh %2,%0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none_0hit")
+ (set_attr "type" "mult")])
+
+;; ??? Sign extending constants isn't valid. Fix?
+
+(define_insn "*mulhisi3_internal2"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (mult:SI
+ (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
+ (sign_extend:SI (match_operand 2 "const_int_operand" "J,K"))))]
+ ""
+ "@
+ mulh %2,%0
+ mulhi %2,%1,%0"
+ [(set_attr "length" "2,4")
+ (set_attr "cc" "none_0hit,none_0hit")
+ (set_attr "type" "mult")])
+
+
+;; ----------------------------------------------------------------------
+;; AND INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "*v850_clr1_1"
+ [(set (match_operand:QI 0 "memory_operand" "=m")
+ (subreg:QI
+ (and:SI (subreg:SI (match_dup 0) 0)
+ (match_operand:QI 1 "not_power_of_two_operand" "")) 0))]
+ ""
+ "*
+{
+ rtx xoperands[2];
+ xoperands[0] = operands[0];
+ xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
+ output_asm_insn (\"clr1 %M1,%0\", xoperands);
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*v850_clr1_2"
+ [(set (match_operand:HI 0 "memory_operand" "=m")
+ (subreg:HI
+ (and:SI (subreg:SI (match_dup 0) 0)
+ (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
+ ""
+ "*
+{
+ int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
+
+ rtx xoperands[2];
+ xoperands[0] = gen_rtx (MEM, QImode,
+ plus_constant (XEXP (operands[0], 0), log2 / 8));
+ xoperands[1] = GEN_INT (log2 % 8);
+ output_asm_insn (\"clr1 %1,%0\", xoperands);
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*v850_clr1_3"
+ [(set (match_operand:SI 0 "memory_operand" "=m")
+ (and:SI (match_dup 0)
+ (match_operand:SI 1 "not_power_of_two_operand" "")))]
+ ""
+ "*
+{
+ int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
+
+ rtx xoperands[2];
+ xoperands[0] = gen_rtx (MEM, QImode,
+ plus_constant (XEXP (operands[0], 0), log2 / 8));
+ xoperands[1] = GEN_INT (log2 % 8);
+ output_asm_insn (\"clr1 %1,%0\", xoperands);
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "andsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
+ (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
+ ""
+ "@
+ and %2,%0
+ and %.,%0
+ andi %2,%1,%0"
+ [(set_attr "length" "2,2,4")
+ (set_attr "cc" "set_znv")])
+
+;; ----------------------------------------------------------------------
+;; OR INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "*v850_set1_1"
+ [(set (match_operand:QI 0 "memory_operand" "=m")
+ (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
+ (match_operand 1 "power_of_two_operand" "")) 0))]
+ ""
+ "set1 %M1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*v850_set1_2"
+ [(set (match_operand:HI 0 "memory_operand" "=m")
+ (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
+ (match_operand 1 "power_of_two_operand" "")) 0))]
+ ""
+ "*
+{
+ int log2 = exact_log2 (INTVAL (operands[1]));
+
+ if (log2 < 8)
+ return \"set1 %M1,%0\";
+ else
+ {
+ rtx xoperands[2];
+ xoperands[0] = gen_rtx (MEM, QImode,
+ plus_constant (XEXP (operands[0], 0), log2 / 8));
+ xoperands[1] = GEN_INT (log2 % 8);
+ output_asm_insn (\"set1 %1,%0\", xoperands);
+ }
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*v850_set1_3"
+ [(set (match_operand:SI 0 "memory_operand" "=m")
+ (ior:SI (match_dup 0)
+ (match_operand 1 "power_of_two_operand" "")))]
+ ""
+ "*
+{
+ int log2 = exact_log2 (INTVAL (operands[1]));
+
+ if (log2 < 8)
+ return \"set1 %M1,%0\";
+ else
+ {
+ rtx xoperands[2];
+ xoperands[0] = gen_rtx (MEM, QImode,
+ plus_constant (XEXP (operands[0], 0), log2 / 8));
+ xoperands[1] = GEN_INT (log2 % 8);
+ output_asm_insn (\"set1 %1,%0\", xoperands);
+ }
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "iorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
+ (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
+ ""
+ "@
+ or %2,%0
+ or %.,%0
+ ori %2,%1,%0"
+ [(set_attr "length" "2,2,4")
+ (set_attr "cc" "set_znv")])
+
+;; ----------------------------------------------------------------------
+;; XOR INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "*v850_not1_1"
+ [(set (match_operand:QI 0 "memory_operand" "=m")
+ (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
+ (match_operand 1 "power_of_two_operand" "")) 0))]
+ ""
+ "not1 %M1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*v850_not1_2"
+ [(set (match_operand:HI 0 "memory_operand" "=m")
+ (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
+ (match_operand 1 "power_of_two_operand" "")) 0))]
+ ""
+ "*
+{
+ int log2 = exact_log2 (INTVAL (operands[1]));
+
+ if (log2 < 8)
+ return \"not1 %M1,%0\";
+ else
+ {
+ rtx xoperands[2];
+ xoperands[0] = gen_rtx (MEM, QImode,
+ plus_constant (XEXP (operands[0], 0), log2 / 8));
+ xoperands[1] = GEN_INT (log2 % 8);
+ output_asm_insn (\"not1 %1,%0\", xoperands);
+ }
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*v850_not1_3"
+ [(set (match_operand:SI 0 "memory_operand" "=m")
+ (xor:SI (match_dup 0)
+ (match_operand 1 "power_of_two_operand" "")))]
+ ""
+ "*
+{
+ int log2 = exact_log2 (INTVAL (operands[1]));
+
+ if (log2 < 8)
+ return \"not1 %M1,%0\";
+ else
+ {
+ rtx xoperands[2];
+ xoperands[0] = gen_rtx (MEM, QImode,
+ plus_constant (XEXP (operands[0], 0), log2 / 8));
+ xoperands[1] = GEN_INT (log2 % 8);
+ output_asm_insn (\"not1 %1,%0\", xoperands);
+ }
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "xorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
+ (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
+ ""
+ "@
+ xor %2,%0
+ xor %.,%0
+ xori %2,%1,%0"
+ [(set_attr "length" "2,2,4")
+ (set_attr "cc" "set_znv")])
+
+;; ----------------------------------------------------------------------
+;; NOT INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "one_cmplsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (not:SI (match_operand:SI 1 "register_operand" "r")))]
+ ""
+ "not %1,%0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "set_znv")])
+
+;; -----------------------------------------------------------------
+;; BIT FIELDS
+;; -----------------------------------------------------------------
+
+;; ??? Is it worth defining insv and extv for the V850 series?!?
+
+;; An insv pattern would be useful, but does not get used because
+;; store_bit_field never calls insv when storing a constant value into a
+;; single-bit bitfield.
+
+;; extv/extzv patterns would be useful, but do not get used because
+;; optimize_bitfield_compare in fold-const usually converts single
+;; bit extracts into an AND with a mask.
+
+;; -----------------------------------------------------------------
+;; Scc INSTRUCTIONS
+;; -----------------------------------------------------------------
+
+(define_insn "sle"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (le:SI (cc0) (const_int 0)))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+ return 0;
+
+ return \"setf le,%0\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sleu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (leu:SI (cc0) (const_int 0)))]
+ ""
+ "setf nh,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sge"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ge:SI (cc0) (const_int 0)))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+ return 0;
+
+ return \"setf ge,%0\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sgeu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (geu:SI (cc0) (const_int 0)))]
+ ""
+ "setf nl,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "slt"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lt:SI (cc0) (const_int 0)))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+ return 0;
+
+ return \"setf lt,%0\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sltu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ltu:SI (cc0) (const_int 0)))]
+ ""
+ "setf l,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sgt"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (gt:SI (cc0) (const_int 0)))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+ return 0;
+
+ return \"setf gt,%0\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sgtu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (gtu:SI (cc0) (const_int 0)))]
+ ""
+ "setf h,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "seq"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (eq:SI (cc0) (const_int 0)))]
+ ""
+ "setf z,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sne"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ne:SI (cc0) (const_int 0)))]
+ ""
+ "setf nz,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+
+;; ----------------------------------------------------------------------
+;; JUMP INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+;; Conditional jump instructions
+
+(define_expand "ble"
+ [(set (pc)
+ (if_then_else (le (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bleu"
+ [(set (pc)
+ (if_then_else (leu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bge"
+ [(set (pc)
+ (if_then_else (ge (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bgeu"
+ [(set (pc)
+ (if_then_else (geu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "blt"
+ [(set (pc)
+ (if_then_else (lt (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bltu"
+ [(set (pc)
+ (if_then_else (ltu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bgt"
+ [(set (pc)
+ (if_then_else (gt (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bgtu"
+ [(set (pc)
+ (if_then_else (gtu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "beq"
+ [(set (pc)
+ (if_then_else (eq (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bne"
+ [(set (pc)
+ (if_then_else (ne (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_insn "*branch_normal"
+ [(set (pc)
+ (if_then_else (match_operator 1 "comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
+ && (GET_CODE (operands[1]) == GT
+ || GET_CODE (operands[1]) == GE
+ || GET_CODE (operands[1]) == LE
+ || GET_CODE (operands[1]) == LT))
+ return 0;
+
+ if (get_attr_length (insn) == 2)
+ return \"b%b1 %l0\";
+ else
+ return \"b%B1 .+6\;jr %l0\";
+}"
+ [(set (attr "length")
+ (if_then_else (lt (abs (minus (match_dup 0) (pc)))
+ (const_int 256))
+ (const_int 2)
+ (const_int 6)))
+ (set_attr "cc" "none")])
+
+(define_insn "*branch_invert"
+ [(set (pc)
+ (if_then_else (match_operator 1 "comparison_operator"
+ [(cc0) (const_int 0)])
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
+ && (GET_CODE (operands[1]) == GT
+ || GET_CODE (operands[1]) == GE
+ || GET_CODE (operands[1]) == LE
+ || GET_CODE (operands[1]) == LT))
+ return 0;
+ if (get_attr_length (insn) == 2)
+ return \"b%B1 %l0\";
+ else
+ return \"b%b1 .+6\;jr %l0\";
+}"
+ [(set (attr "length")
+ (if_then_else (lt (abs (minus (match_dup 0) (pc)))
+ (const_int 256))
+ (const_int 2)
+ (const_int 6)))
+ (set_attr "cc" "none")])
+
+;; Unconditional and other jump instructions.
+
+(define_insn "jump"
+ [(set (pc)
+ (label_ref (match_operand 0 "" "")))]
+ ""
+ "*
+{
+ if (get_attr_length (insn) == 2)
+ return \"br %0\";
+ else
+ return \"jr %0\";
+}"
+ [(set (attr "length")
+ (if_then_else (lt (abs (minus (match_dup 0) (pc)))
+ (const_int 256))
+ (const_int 2)
+ (const_int 4)))
+ (set_attr "cc" "none")])
+
+(define_insn "indirect_jump"
+ [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
+ ""
+ "jmp %0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
+(define_insn "tablejump"
+ [(set (pc) (match_operand:SI 0 "register_operand" "r"))
+ (use (label_ref (match_operand 1 "" "")))]
+ ""
+ "jmp %0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
+(define_expand "casesi"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")
+ (match_operand 3 "" "") (match_operand 4 "" "")]
+ ""
+ "
+{
+ rtx reg = gen_reg_rtx (SImode);
+ rtx tableaddress = gen_reg_rtx (SImode);
+ rtx mem;
+
+ /* Subtract the lower bound from the index. */
+ emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
+ /* Compare the result against the number of table entries. */
+ emit_insn (gen_cmpsi (reg, operands[2]));
+ /* Branch to the default label if out of range of the table. */
+ emit_jump_insn (gen_bgtu (operands[4]));
+
+ /* Shift index for the table array access. */
+ emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
+ /* Load the table address into a pseudo. */
+ emit_insn (gen_movsi (tableaddress,
+ gen_rtx (LABEL_REF, VOIDmode, operands[3])));
+ /* Add the table address to the index. */
+ emit_insn (gen_addsi3 (reg, reg, tableaddress));
+ /* Load the table entry. */
+ mem = gen_rtx (MEM, CASE_VECTOR_MODE, reg);
+ RTX_UNCHANGING_P (mem);
+ if (! TARGET_BIG_SWITCH)
+ {
+ rtx reg2 = gen_reg_rtx (HImode);
+ emit_insn (gen_movhi (reg2, mem));
+ emit_insn (gen_extendhisi2 (reg, reg2));
+ }
+ else
+ emit_insn (gen_movsi (reg, mem));
+ /* Add the table address. */
+ emit_insn (gen_addsi3 (reg, reg, tableaddress));
+ /* Branch to the switch label. */
+ emit_jump_insn (gen_tablejump (reg, operands[3]));
+ DONE;
+}")
+
+;; Call subroutine with no return value.
+
+(define_expand "call"
+ [(call (match_operand:QI 0 "general_operand" "")
+ (match_operand:SI 1 "general_operand" ""))]
+ ""
+ "
+{
+ if (! call_address_operand (XEXP (operands[0], 0))
+ || TARGET_LONG_CALLS)
+ XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
+ emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
+ DONE;
+}")
+
+(define_insn "call_internal"
+ [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
+ (match_operand:SI 1 "general_operand" "g,g"))
+ (clobber (reg:SI 31))]
+ ""
+ "@
+ jarl %0,r31
+ jarl .+4,r31\\n\\tadd 4,r31\\n\\tjmp %0"
+ [(set_attr "length" "4,8")])
+
+;; Call subroutine, returning value in operand 0
+;; (which must be a hard register).
+
+(define_expand "call_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ ""
+ "
+{
+ if (! call_address_operand (XEXP (operands[1], 0))
+ || TARGET_LONG_CALLS)
+ XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
+ emit_call_insn (gen_call_value_internal (operands[0],
+ XEXP (operands[1], 0),
+ operands[2]));
+ DONE;
+}")
+
+(define_insn "call_value_internal"
+ [(set (match_operand 0 "" "=r,r")
+ (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
+ (match_operand:SI 2 "general_operand" "g,g")))
+ (clobber (reg:SI 31))]
+ ""
+ "@
+ jarl %1,r31
+ jarl .+4,r31\\n\\tadd 4,r31\\n\\tjmp %1"
+ [(set_attr "length" "4,8")])
+
+(define_insn "nop"
+ [(const_int 0)]
+ ""
+ "nop"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
+;; ----------------------------------------------------------------------
+;; EXTEND INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+
+(define_insn "zero_extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI
+ (match_operand:HI 1 "register_operand" "r")))]
+ ""
+ "andi 65535,%1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "set_znv")])
+
+
+(define_insn "zero_extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI
+ (match_operand:QI 1 "register_operand" "r")))]
+ ""
+ "andi 255,%1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "set_znv")])
+
+;;- sign extension instructions
+
+
+;; ??? This is missing a sign extend from memory pattern to match the ld.h
+;; instruction.
+
+(define_expand "extendhisi2"
+ [(set (match_dup 2)
+ (ashift:SI (match_operand:HI 1 "register_operand" "")
+ (const_int 16)))
+ (set (match_operand:SI 0 "register_operand" "")
+ (ashiftrt:SI (match_dup 2)
+ (const_int 16)))]
+ ""
+ "
+{
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = gen_reg_rtx (SImode);
+}")
+
+
+;; ??? This is missing a sign extend from memory pattern to match the ld.b
+;; instruction.
+
+(define_expand "extendqisi2"
+ [(set (match_dup 2)
+ (ashift:SI (match_operand:QI 1 "register_operand" "")
+ (const_int 24)))
+ (set (match_operand:SI 0 "register_operand" "")
+ (ashiftrt:SI (match_dup 2)
+ (const_int 24)))]
+ ""
+ "
+{
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = gen_reg_rtx (SImode);
+}")
+
+;; ----------------------------------------------------------------------
+;; SHIFTS
+;; ----------------------------------------------------------------------
+
+(define_insn "ashlsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (ashift:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "r,N")))]
+ ""
+ "@
+ shl %2,%0
+ shl %2,%0"
+ [(set_attr "length" "4,2")
+ (set_attr "cc" "set_znv")])
+
+(define_insn "lshrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (lshiftrt:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "r,N")))]
+ ""
+ "@
+ shr %2,%0
+ shr %2,%0"
+ [(set_attr "length" "4,2")
+ (set_attr "cc" "set_znv")])
+
+(define_insn "ashrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (ashiftrt:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "r,N")))]
+ ""
+ "@
+ sar %2,%0
+ sar %2,%0"
+ [(set_attr "length" "4,2")
+ (set_attr "cc" "set_znv")])
+
+;; ----------------------------------------------------------------------
+;; PROLOGUE/EPILOGUE
+;; ----------------------------------------------------------------------
+(define_expand "prologue"
+ [(const_int 0)]
+ ""
+ "expand_prologue (); DONE;")
+
+(define_expand "epilogue"
+ [(return)]
+ ""
+ "
+{
+ /* Try to use the trivial return first. Else use the
+ full epilogue. */
+ if (0)
+ emit_jump_insn (gen_return ());
+ else
+ expand_epilogue ();
+ DONE;
+}")
+
+(define_insn "return"
+ [(return)]
+ "reload_completed && compute_frame_size (get_frame_size (), (long *)0) == 0"
+ "jmp [r31]"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
+(define_insn "return_internal"
+ [(return)
+ (use (reg:SI 31))]
+ ""
+ "jmp [r31]"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
+
+
+;; ----------------------------------------------------------------------
+;; HELPER INSTRUCTIONS for saving the prologue and epilog registers
+;; ----------------------------------------------------------------------
+
+;; This pattern will match a stack adjust RTX followed by any number of push
+;; RTXs. These RTXs will then be turned into a suitable call to a worker
+;; function.
+
+
+(define_insn ""
+ [(match_parallel 0 "pattern_is_ok_for_prologue"
+ [(set (reg:SI 3)
+ (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
+ (set (mem:SI (plus:SI (reg:SI 3)
+ (match_operand:SI 2 "immediate_operand" "i")))
+ (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
+ "TARGET_PROLOG_FUNCTION"
+ "* return construct_save_jarl (operands[0]);
+ "
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+
+;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
+(define_insn "save_interrupt"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 30))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 4))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))]
+ ""
+ "add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10"
+ [(set_attr "length" "12")
+ (set_attr "cc" "clobber")])
+
+
+;; Save all registers except for the registers saved in save_interrupt when
+;; an interrupt function makes a call.
+;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
+;; all of memory. This blocks insns from being moved across this point.
+;; This is needed because the rest of the compiler is not ready to handle
+;; insns this complicated.
+
+(define_insn "save_all_interrupt"
+ [(unspec_volatile [(const_int 0)] 0)]
+ ""
+ "jarl __save_all_interrupt,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+
+
+
+;; This pattern will match a return RTX followed by any number of pop RTXs
+;; and possible a stack adjustment as well. These RTXs will be turned into
+;; a suitable call to a worker function.
+
+
+(define_insn ""
+[(match_parallel 0 "pattern_is_ok_for_epilogue"
+ [(return)
+ (set (reg:SI 3)
+ (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
+ (set (match_operand:SI 2 "register_is_ok_for_epilogue" "r")
+ (mem:SI (plus:SI (reg:SI 3)
+ (match_operand:SI 3 "immediate_operand" "i"))))])]
+ "TARGET_PROLOG_FUNCTION && TARGET_V850"
+ "* return construct_restore_jr (operands[0]);
+ "
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r1, r4, r10, and return from the interrupt
+(define_insn "restore_interrupt"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16)))
+ (set (reg:SI 30) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
+ (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
+ (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
+ (set (reg:SI 1) (mem:SI (reg:SI 3)))]
+ ""
+ "jr __return_interrupt"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore all registers saved when an interrupt function makes a call.
+;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
+;; all of memory. This blocks insns from being moved across this point.
+;; This is needed because the rest of the compiler is not ready to handle
+;; insns this complicated.
+
+(define_insn "restore_all_interrupt"
+ [(unspec_volatile [(const_int 0)] 1)]
+ ""
+ "jarl __restore_all_interrupt,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r6-r9 for a variable argument function
+(define_insn "save_r6_r9"
+ [(set (mem:SI (reg:SI 3)) (reg:SI 6))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r6_r9,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
diff --git a/gnu/usr.bin/gcc/config/v850/xm-v850.h b/gnu/usr.bin/gcc/config/v850/xm-v850.h
new file mode 100644
index 00000000000..1e43d033f6f
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/v850/xm-v850.h
@@ -0,0 +1,49 @@
+/* Configuration for NEC V850.
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+
+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 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
+
+#ifdef __v850
+#ifndef __STDC__
+extern char *malloc (), *realloc (), *calloc ();
+#else
+extern void *malloc (), *realloc (), *calloc ();
+#endif
+extern void free ();
+#endif
+
+/* target machine dependencies.
+ tm.h is a symbolic link to the actual target specific file. */
+
+#include "tm.h"
diff --git a/gnu/usr.bin/gcc/config/xm-std32.h b/gnu/usr.bin/gcc/config/xm-std32.h
new file mode 100644
index 00000000000..c52782e9741
--- /dev/null
+++ b/gnu/usr.bin/gcc/config/xm-std32.h
@@ -0,0 +1,34 @@
+/* Configuration for GNU C-compiler for standard 32-bit host machine.
+ Copyright (C) 1997 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 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
diff --git a/gnu/usr.bin/gcc/cp/ChangeLog.1 b/gnu/usr.bin/gcc/cp/ChangeLog.1
new file mode 100644
index 00000000000..024a4e62126
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/ChangeLog.1
@@ -0,0 +1,9451 @@
+Sun Nov 26 14:47:42 1995 Richard Kenner <kenner@mole.gnu.ai.mit.edu>
+
+ * Version 2.7.2 released.
+
+Mon Nov 20 14:05:00 1995 Mike Stump <mrs@cygnus.com>
+
+ * g++.c (pfatal_with_name): Add missing third argument to concat.
+
+Thu Oct 26 13:59:54 1995 Mike Stump <mrs@cygnus.com>
+
+ * init.c (expand_aggr_init): Handle cv qualifiers on the object's
+ type.
+
+Sat Nov 11 08:25:55 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Version 2.7.1 released.
+
+Thu Nov 2 17:02:47 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (convert_harshness): Handle references to arrays.
+
+Fri Oct 27 14:20:21 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (comp_target_types): Check multi-level pointer
+ conversions in both directions.
+
+Tue Oct 17 21:39:05 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (explicit_instantiation): Fix 'extern template' with no
+ return type.
+
+Mon Oct 16 14:35:20 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (explicit_instantiation): Support automatic instantiation
+ of constructors.
+ (named_class_head_*): Support out-of-class definition of nested
+ types.
+
+Wed Oct 11 12:20:56 1995 Mike Stump <mrs@cygnus.com>
+
+ * search.c (envelope_add_decl): New routine. Fix so that
+ methods are hidden in the same way that other members are.
+ (dfs_pushdecls): Cleanup and move functionality out of line,
+ into envelope_add_decl.
+
+Tue Oct 10 15:46:01 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (mark_addressable): Only call assemble_external if we
+ have started the output file.
+
+Tue Oct 10 11:27:18 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_function): Fix earlier cv-quals change.
+
+Mon Oct 9 23:53:05 1995 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (complex_direct_notype_declarator): Only push the class if
+ we are not already in the class.
+
+Mon Oct 9 11:22:03 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * decl.c (duplicate_decls): Call merge_machine_decl_attributes.
+ Update olddecl's attributes too.
+ (grokdeclarator): #if 0 out call to build_decl_attribute_variant.
+ * typeck.c (common_type): Call merge_machine_type_attributes.
+
+Fri Oct 6 14:44:27 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (mark_addressable): Add missing call to
+ assemble_external.
+
+Wed Oct 4 15:06:39 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (store_parm_decls): Make sure the unwinder start comes
+ before the exception specification start.
+ * except.c (expand_exception_blocks): Make sure the unwinder end
+ comes after the terminate protected catch clause region and after
+ the end of the exception specification region.
+
+Wed Oct 4 12:47:02 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (real_yylex): Fix identifier case for linemode.
+ (handle_sysv_pragma): Don't abort when we see a pragma we don't
+ recognize.
+
+Tue Oct 3 14:09:46 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (store_parm_decls): Add a call to start_eh_unwinder.
+ * except.c (init_exception_processing): __throw doesn't take any
+ arguments.
+ (expand_builtin_throw): Likewise. Always use Pmode, instead of SImode
+ for all pointers. Use expand_builtin_return_addr to unwind the
+ first level off the stack.
+ (do_unwind): Always use Pmode, instead of SImode for all pointers.
+ (expand_exception_blocks): Add a call to end_eh_unwinder.
+ (start_eh_unwinder, end_eh_unwinder): New routines to build machine
+ independent stack unwinders for function/method calls.
+
+Mon Oct 2 17:20:42 1995 Mike Stump <mrs@cygnus.com>
+
+ * tree.c (unsave_expr_now): Make sure we process the argument list
+ of any called functions. Fixes incorrect code generation for
+ cleanups.
+
+Mon Oct 2 13:04:16 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Save function if it
+ needs it. Cures core dump on things like (this->*(f()))().
+
+Sat Sep 23 22:51:25 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (start_function): Conform to gcc cv-quals convention (no
+ expression has a cv-qualified type) in RESULT_DECLs.
+ * method.c (make_thunk): Likewise.
+
+Fri Sep 22 10:21:13 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (pushtag): Add in the namespace name for the tag.
+
+Thu Sep 21 13:11:13 1995 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (maybe_base_class_list, base_class_list, base_class,
+ base_class_access_list): Make sure we see the typenames for base
+ classes.
+ * lex.c (see_typename): Instead of failing to see a typename when
+ there is no next token, perfer a typename, and get the next token.
+
+Wed Sep 20 12:35:27 1995 Michael Meissner <meissner@cygnus.com>
+
+ * decl.c (init_decl_processing): Add __builtin_expect.
+
+Tue Sep 19 16:48:11 1995 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): Don't allow leftover conversions to
+ or from pointer to member functions, they must all be handled before
+ this point.
+
+Fri Sep 15 17:14:47 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (resolve_offset_ref): Fix wording of non-static member
+ being referenced as a static.
+
+Fri Sep 15 12:39:11 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_indirect_ref): Only bash pointer if we actually
+ call build_expr_type_conversion.
+
+Thu Sep 14 18:24:56 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (build_expr_type_conversion): Handle conversion from
+ reference.
+ * typeck.c (build_indirect_ref): Avoid infinite recursion.
+
+Thu Sep 14 17:23:28 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (expand_start_early_try_stmts): New routine to start a try
+ block at the start of the function, for function-try-blocks.
+ * cp-tree.h (expand_start_early_try_stmts): Declare it.
+ * parse.y (function_try_block): Use it, instead of doing it here, as
+ we don't want to include rtl.h here, as that conflicts with RETURN
+ in the parser.
+
+Wed Sep 13 18:32:24 1995 Mike Stump <mrs@cygnus.com>
+
+ * lex.c (reinit_parse_for_block): Support saving inline
+ function-try-blocks, uses peekyylex.
+ * parse.y (eat_saved_input): New rule, permit the parser to see that
+ END_OF_SAVED_INPUT is ok, as it can see this when parsing the
+ handlers of a function-try-block.
+ (fndef): Use it.
+ (component_decl): Make sure TRY and RETURN can come after fn.def2.
+ * spew.c (peekyylex): New routine to peek at what will come next.
+
+Wed Sep 13 16:52:06 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (comptypes): Tighten up comparisons of template type
+ parms.
+
+ * decl.c (duplicate_decls): Turn off whining about virtual functions
+ redeclared inline for now.
+
+Wed Sep 13 11:13:40 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (store_in_parms): New routine to put things before we
+ put base inits.
+ * cp-tree.h (store_in_parms): Declare it.
+ * decl.c (store_parm_decls): Use it to makr sure the starting of the
+ eh spec comes before base inits.
+ (finish_function): Use sequences instead of the obsolete
+ reorder_insns.
+ * parse.y (fndef): Enhance readability and maintainability. Update
+ to include function_try_block syntax.
+ (function_try_block): Add.
+
+Tue Sep 12 17:43:07 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c (convert_harshness): Use comptypes, not ==, to check if
+ TYPE and PARMTYPE are equivalent on a function type.
+
+Tue Sep 12 17:31:33 1995 Douglas Rupp <drupp@cs.washington.edu>
+
+ * Make-lang.in (cc1plus) : Removed unnecessary $(exeext).
+
+Mon Sep 11 23:24:07 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Never allocate storage for thrown pointer
+ to objects.
+
+Mon Sep 11 19:36:45 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_start_catch_block): Pointers to objects come
+ back from catch matching already dereferenced, don't dereference
+ again.
+
+Mon Sep 11 15:46:28 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Only decay the throw expression, don't do
+ any default conversions. This is so that one can throw and catch
+ characters, and not have them match integers.
+
+Mon Sep 11 13:46:45 1995 Mike Stump <mrs@cygnus.com>
+
+ * error.c (dump_aggr_type): Deal with anonymous unions that don't
+ have a TYPE_NAME.
+
+Fri Sep 8 20:40:27 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * lex.c (handle_sysv_pragma): Deal with getting a comma from yylex.
+
+Fri Sep 8 15:51:41 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_end_eh_spec): Handle empty EH specifications.
+
+Fri Sep 8 15:27:22 1995 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (expand_start_eh_spec): Declare new routine.
+ (expand_end_eh_spec): Likewise.
+ * decl.c (store_parm_decls): Call expand_start_eh_spec to process
+ exception specifications.
+ * except.c (expand_leftover_cleanups): Remove unused parameter.
+ (expand_end_catch_block): Likewise.
+ (expand_exception_blocks): Likewise.
+ (expand_start_eh_spec): New routine to mark the start of an
+ exception specification region.
+ (expand_end_eh_spec): New routine to mark the end of an exception
+ specification region.
+ (expand_exception_blocks): Call expand_end_eh_spec to process
+ exception specifications.
+
+Fri Sep 8 14:40:48 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * lex.c (do_identifier): Use global binding in preference of
+ dead for local variable.
+
+Wed Sep 6 19:32:59 1995 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (build_exception_variant): Remove used first argument.
+ * decl.c (duplicate_decls): Likewise.
+ (grokfndecl): Likewise.
+ (revert_static_member_fn): Likewise.
+ * decl2.c (grok_method_quals): Likewise.
+ * tree.c (build_exception_variant): Likewise.
+ * typeck.c (common_type): Likewise.
+ * decl2.c (grokclassfn): After changing the type, call
+ build_exception_variant, if necessary.
+
+Tue Sep 5 15:56:27 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Run cleanups for the throw expression.
+
+Wed Aug 30 15:24:38 1995 Stephen L. Favor <sfavor@tigger.intecom.com>
+
+ * except.c (expand_builtin_throw): Moved gen_label_rtx calls beyond
+ the store_parm_decls call which does initialization in the emit_*
+ code concerning label numbering.
+
+Thu Aug 31 09:01:07 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_internal_throw): Let the frontend be responsible
+ for managing all frontend EH parameters, the backend routine only
+ needs to deal with backend values. type and value are no longer
+ passed to __throw.
+ (init_exception_processing): Likewise.
+ (expand_start_all_catch): Likewise.
+ (expand_end_all_catch): Likewise.
+ (expand_leftover_cleanups): Likewise.
+ (expand_end_catch_block): Likewise.
+ (expand_builtin_throw): Likewise.
+ (expand_throw): Likewise.
+
+Tue Aug 29 15:04:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cp-tree.h (DECL_REAL_CONTEXT): Give the real declaration context
+ for a decl.
+ * decl.c (cp_finish_decl): Use it.
+
+Tue Aug 29 10:30:27 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_internal_throw): Oops, almost forgot type and
+ value are now trees.
+
+Mon Aug 28 17:57:45 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ Fix the attribute handling to make sure they get noted before we
+ create the function's RTL, in case they can affect that.
+ * decl.c (grokfndecl): New arg ATTRLIST. Run
+ cplus_decl_attributes before creating the decl's rtl.
+ (grokdeclarator): New arg ATTRLIST, passed down into grokfndecl.
+ (shadow_tag, groktypename, start_decl, start_method): Pass a
+ NULL_TREE to grokdeclarator's new last arg.
+ * decl2.c (grokfield): New arg ATTRLIST, passed into grokdeclarator.
+ (grokbitfield, grokoptypename): Pass a NULL_TREE to
+ grokdeclarator's new last arg.
+ * except.c (expand_start_catch_block): Likewise.
+ * pt.c (process_template_parm, end_template_decl,
+ do_function_instantiation): Likewise.
+ * cp-tree.h (grokfield): Add arg.
+ (grokdeclarator): Move the prototype from here...
+ * decl.h: ...to here.
+ * lex.c (cons_up_default_function): Pass NULL_TREE to grokfield
+ ATTRLIST argument.
+ * parse.y: Create a list for the grokfield arg where appropriate,
+ and pass it down instead of calling cplus_decl_attributes.
+
+Mon Aug 28 15:07:24 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Always allow turning on exception handling. Allow cross
+ compilations to use EH.
+
+Thu Aug 24 17:39:24 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (saved_pc, saved_throw_type, saved_throw_value): Use
+ trees, instead of rtxs, and don't depend on using special machine
+ dependent registers.
+ (expand_internal_throw): Likewise.
+ (init_exception_processing): Likewise.
+ (expand_start_all_catch): Likewise.
+ (expand_end_all_catch): Likewise.
+ (expand_start_catch_block): Likewise.
+ (expand_leftover_cleanups): Likewise.
+ (expand_end_catch_block): Likewise.
+ (expand_builtin_throw): Likewise.
+ (expand_throw): Likewise.
+
+Wed Aug 23 17:25:51 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (build_expr_type_conversion): Handle conversions to
+ reference types.
+
+Wed Aug 23 15:33:59 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (do_unwind): Work around backend bug with -fpic.
+
+Tue Aug 22 17:20:07 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl2.c (flag_new_for_scope): Add a new mode that follows ANSI
+ for-scoping, but supports (and warns about) old programs.
+ Make the new mode (with value 1) the default.
+ (lang_f_options): The on-value for flag_new_for_scope is now 2.
+ * cp-tree.h (DECL_DEAD_FOR_LOCAL, DECL_ERROR_REPORTED): New macros
+ (DECL_SHADOWED_FOR_VAR): Likewise.
+ * decl.c (struct binding_level): New fields dead_vars_from_for
+ and is_for_scope.
+ (note_level_for_for): New function.
+ (poplevel): Special processing if is_for_scope.
+ (pushdecl): Warn if for-scope variable shadows local.
+ * lex.c (do_identifier): Handle old (non-ANSI) for scoping,
+ and warn if conflicts.
+ * parse.y (FOR): Call note_level_for_for.
+
+Mon Aug 21 10:28:31 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (import_export_inline): Class interface hackery does not
+ apply to synthesized methods.
+
+Sun Aug 20 16:29:00 1995 Mike Stump <mrs@cygnus.com>
+
+ * search.c (virtual_context): Find the right context more often.
+ Solves a `recoverable compiler error, fixups for virtual function'
+ problem.
+
+Sun Aug 20 13:53:24 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_start_all_catch): Ensure that we always transfer
+ control to the right EH handler, by rethrowing the end label on the
+ region, instead of hoping we are nested and falling through.
+ (expand_leftover_cleanups): Likewise.
+ (end_protect): Since we now rethrow the end label, put a
+ nop after it, so that outer regions are recognized.
+ * init.c (build_vec_delete_1): New routine to handle most of vector
+ deleting, all code moved here from build_vec_delete.
+ (build_array_eh_cleanup): Use build_vec_delete_1 to do all the real
+ work.
+ (expand_vec_init): If the array needs partial destructing, setup an
+ EH region to handle it.
+ (build_vec_delete): Move lots of code to build_vec_delete_1, use
+ build_vec_delete_1 to do the grunt work.
+
+Sat Aug 19 14:25:33 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ Handle decl attributes properly for function definitions without
+ previous attribute-loaded declarations.
+ * decl.c (start_function): New arg ATTRS. Add a call to
+ cplus_decl_attributes with it before we create the RTL.
+ * cp-tree.h (start_function): Update prototype.
+ * parse.y (fn.def1): Pass ATTRS into start_function instead of
+ trying to call cplus_decl_attributes too late. Pass a NULL_TREE
+ for other use.
+ * decl2.c (finish_file): Pass NULL_TREE as fourth arg to
+ start_function.
+ * method.c (synthesize_method): Likewise.
+ * except.c (expand_builtin_throw): Likewise for start on __throw.
+
+Sat Aug 19 13:36:08 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (set_rtti_entry): Turn on -fvtable-thunk -frtti support.
+ This changes -fvtable-thunks vtable layout, so a recompile will be
+ necessary, if you use -fvtable-thunks.
+ (get_vtable_entry): Use n, instead of i to be consistent with the
+ rest of the compiler.
+ (get_vtable_entry_n): Likewise.
+ (add_virtual_function): Add a slot for the tdesc, if -fvtable-thunks
+ are being used.
+ (finish_struct_1): Likewise.
+ (skip_rtti_stuff): New routine to collapse similar code from many
+ different parts of the compiler. I think I got them all.
+ (modify_one_vtable): Use it.
+ (fixup_vtable_deltas1): Likewise.
+ (override_one_vtable): Likewise.
+ * decl2.c (mark_vtable_entries): Likewise.
+ * tree.c (debug_binfo): Likewise.
+ * search.c (expand_upcast_fixups): Likewise.
+ (get_abstract_virtuals_1): Likewise. Use virtuals, instead of tmp to
+ consistent with the rest of the compiler.
+ (get_abstract_virtuals): Likewise.
+ * cp-tree.h (skip_rtti_stuff): New routine, declare it.
+ * gc.c (build_headof): Support -fvtable-thunk and -frtti together.
+ (build_typeid): Likewise.
+ (build_classof): Remove old style way of doing rtti. Remove support
+ for `classof' and `headof'.
+ * gxx.gperf: Likewise.
+ * hash.h: Likewise.
+ * parse.y: Likewise.
+
+Fri Aug 18 17:31:58 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (start_function): Clear ctor_label and dtor_label.
+
+ * class.c (finish_struct_1): Fix handling of access decls.
+
+Tue Aug 15 19:21:54 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (finish_struct): Only do minimal processing here, so it
+ can be used for class template definitions, as well.
+ (finish_struct_1): New function with the rest of the code.
+
+Tue Aug 15 09:46:16 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (prepare_fresh_vtable): On second though, always build the
+ offset (see Aug 10 change), unless -fvtable-thunks is given. It
+ does this by calling the new routine set_rtti_entry.
+ (finish_struct): Likewise.
+ (set_rtti_entry): New routine to update the rtti information at the
+ start of the vtable.
+
+Mon Aug 14 12:21:22 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * error.c (dump_decl, case IDENTIFIER_NODE): Only work on a dtor
+ if it's declared in the C++ language spec.
+ (dump_function_decl): Likewise.
+ (dump_function_name): Likewise.
+ (ident_fndecl): Make sure we got something back from lookup_name.
+ * decl.c (start_function): Likewise.
+
+Fri Aug 11 16:52:15 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Don't call build_new when calling a
+ constructor without an instance.
+
+Thu Aug 10 20:00:17 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (prepare_fresh_vtable): Always build the offset to the
+ complete object, as it doesn't cost much. This allows dynamic_cast
+ to void * to work when -frtti isn't given.
+ (finish_struct): Likewise.
+
+Thu Aug 10 16:31:28 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (build_eh_type): Split out some functionality to new
+ routine named build_eh_type_type.
+ (build_eh_type_type): New routine.
+ (expand_start_catch_block): Use build_eh_type_type, as we never want
+ the dynamic type of the catch parameter, just the static type.
+ Fixes core dumps when -frtti is used and one catchs pointers to
+ classes.
+
+Thu Aug 10 14:55:29 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_builtin_throw): Since we now use normal calling
+ conventions for __throw, we have to remove the first layer off the
+ stack, so that the next context we search for handlers is the outer
+ context instead of the context that had the call to __throw, if we
+ don't immediately find the desired context.
+
+Tue Aug 8 17:44:23 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * tree.c (cp_expand_decl_cleanup): Returns int, not tree.
+ * cp-tree.h: Update.
+
+ * parse.y (template_type_parm): Add support for `typename'.
+
+Tue Aug 8 12:06:31 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_internal_throw): New internal routine to throw a
+ value.
+ (expand_end_all_catch, expand_leftover_cleanups): All throwers
+ changed to use `expand_internal_throw' instead of jumping to throw
+ label.
+ (expand_end_catch_block, expand_throw): Likewise.
+ (throw_label): Removed.
+ (expand_builtin_throw): Changed so that EH parameters are passed by
+ normal function call conventions. Completes Aug 4th work.
+
+Fri Aug 4 17:17:08 1995 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (expand_builtin_throw): Declare it.
+ * decl2.c (finish_file): Call expand_builtin_throw.
+ * except.c (make_first_label): Remove.
+ (init_exception_processing): Don't use a LABEL_REF for throw_label,
+ instead use a SYMBOL_REF, this is so that we don't use LABEL_REFs in
+ other functions that don't really appear in those functions. This
+ solves a problem where cc1plus consumed exponential amounts of
+ memory when -Wall was used.
+ (expand_end_all_catch, expand_leftover_cleanups,
+ expand_end_catch_block, expand_throw): Change all uses of
+ throw_label to match new style.
+ (do_unwind): Rename parameter to inner_throw_label, as it is now
+ different from throw_label. Also, assume that our caller will wrap
+ the passed label with a LABEL_REF, if needed.
+ (expand_builtin_throw): Make external, change so that the generated
+ throw is now a real function.
+ (expand_exception_blocks): Never generate throw code inside another
+ function.
+
+Fri Aug 4 12:20:02 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (grokdeclarator): Move checking of mutable const objects
+ and mutable static objects down, as we might decide during parsing
+ to unset staticp or constp (for example, when const is part of the
+ object being pointed to).
+
+Thu Aug 3 17:13:43 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (output_exception_table_entry): Enhance portability to
+ weird machines.
+ (emit_exception_table): Likewise.
+
+Thu Aug 3 16:41:38 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_ptrmemfunc): Handle casting of pointer to
+ non-virtual member functions.
+
+Wed Aug 2 11:58:25 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_typeid): Strip cv qualifiers so that const T&, T&, T
+ and const T all match.
+
+Wed Aug 2 11:25:33 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (build_eh_type): Strip cv qualifiers so that const T&,
+ T&, T and const T all match.
+
+Tue Aug 1 14:20:16 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Fix up comments, cleanup code and eliminate exceptNode,
+ exceptStack, exceptstack, push_except_stmts, pop_except_stmts,
+ new_except_stack, push_last_insn, pop_last_insn, insn_save_node and
+ InsnSave. Also, numerous speed improvements, and correctness
+ improvements. Double faulting in all situations should now be
+ handled correctly.
+ (expand_start_all_catch): Instead of having many terminate protected
+ regions, just have one.
+ (expand_start_catch_block): No longer have to protect
+ false_label_rtx, as it isn't used for EH region marking.
+ (expand_end_catch_block): Expand out EH cleanups here by using
+ expand_leftover_cleanups.
+ (expand_end_all_catch): Use sequences instead of playing with insn
+ links directly.
+ (expand_exception_blocks): Likewise. Also protect all catch clauses
+ with one terminate region.
+
+Mon Jul 31 13:24:30 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (report_type_mismatch): Don't talk about an object
+ parameter for non-methods.
+
+Sun Jul 30 13:13:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (finish_struct): Catch private and protected members of
+ anonymous unions here.
+ * decl2.c (finish_anon_union): And here.
+ * parse.y: Instead of here.
+
+ * errfn.c (ARGSLIST): Support passing four args.
+ * error.c (cv_as_string): New function.
+ (cp_printers): Add it.
+ * call.c (build_method_call): Report 'const' at end of pseudo-decl.
+
+ * method.c (report_type_mismatch): Deal with a bad_arg of 0.
+
+ * init.c (expand_aggr_init): Handle volatile objects, too.
+
+Sat Jul 29 13:42:03 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (struct binding_level): Keep list of incomplete decls.
+ (print_binding_level): Use list_length to count them.
+ (pushdecl): Build up the list.
+ (hack_incomplete_structures): Walk it and prune completed decls.
+
+Fri Jul 28 15:26:44 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (comp_target_types): Don't check const and volatile for
+ function types.
+ (comp_ptr_ttypes_real): Likewise.
+
+Thu Jul 27 15:40:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (comp_target_types): Fix.
+
+Thu Jul 27 15:10:48 1995 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (unsave_expr_now, build_unsave_expr,
+ cp_expand_decl_cleanup): Declare new routines.
+ * decl.c (cp_finish_decl, store_parm_decls,
+ hack_incomplete_structures): Change all cals from
+ expand_decl_cleanup to cp_expand_decl_cleanup.
+ * gc.c (protect_value_from_gc): Likewise.
+ * expr.c (cplus_expand_expr): Handle UNSAVE_EXPRs.
+ * tree.c (unsave_expr): New routine to build an UNSAVE_EXPR.
+ (unsave_expr_now): Backend routine used by tree expander.
+ (cp_expand_decl_cleanup): Wrap second argument in an UNSAVE_EXPR to
+ work around a limitation in the backend. The backend uses the
+ cleanups multiple times, on disjoint control flows, so we cannot
+ pass unsaved SAVE_EXPRs to the backend.
+ * tree.def (UNSAVE_EXPR): New tree code.
+ * typeck.c (c_expand_return): Move goto/return code up inside
+ conditional, as we don't always want to do this, we only want to do
+ this when we don't otherwise finish with this control flow.
+
+Thu Jul 27 10:38:43 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (typespec): Only complain about typeof if we're not
+ getting it from a system header.
+
+Thu Jul 27 10:26:23 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ Clean up prefix attribute handling.
+ * parse.y (reserved_declspecs): Link prefix attributes with declspecs.
+ (declmods): Likewise.
+ (all rules that reference typed_declspecs and declmods): Call
+ split_specs_attrs or strip_attrs to separate declspecs and attrs.
+ (lang_extdef): Delete resetting of prefix_attributes.
+ (template_def, notype_declarator rule): Use NULL_TREE for
+ prefix_attributes.
+ (condition): Use NULL_TREE for prefix_attributes.
+ (setattrs): Deleted.
+ (nomods_initdcl0): Set prefix_attributes to NULL_TREE.
+ (component_decl): Delete resetting of prefix_attributes.
+ (component_decl_1, notype_components rule): Use NULL_TREE for
+ prefix_attributes.
+ (simple_stmt): Delete resetting of prefix_attributes.
+
+Mon Jul 24 13:37:53 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (convert_harshness): Deal with reference conversions before
+ others. Actually do array->pointer decay. Call comp_target_types
+ with pointer types rather than their targets.
+
+ * typeck.c (comp_target_types): Avoid assigning D const * to B *.
+
+Mon Jul 24 08:54:46 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * pt.c (to_be_restored): Move decl to global scope.
+
+Sat Jul 22 12:22:11 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (start_decl): Put back clearing of DECL_IN_AGGR_P.
+
+Fri Jul 21 17:09:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grokdeclarator): Downgrade error about 'extern int A::i'
+ to pedwarn.
+
+ * pt.c (instantiate_template): Also avoid instantiation if the
+ function has already been declared to be a specialization.
+
+ * decl2.c (check_classfn): Ignore cname argument, and return the
+ matching function.
+
+ * decl.c (start_decl): Handle declarations of member functions
+ outside of the class (i.e. specialization declarations).
+
+Thu Jul 20 10:34:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (finish_struct): Don't mess with the type of bitfields.
+
+ * various.c: s/TYPE_POINTER_TO/build_pointer_type/.
+
+Thu Jul 20 01:43:10 1995 Mike Stump <mrs@cygnus.com>
+
+ * init.c (expand_aggr_init): Assume LOOKUP_ONLYCONVERTING if init
+ is not a parameter list (TREE_LIST).
+ (expand_default_init): If LOOKUP_ONLYCONVERTING is set, then set
+ LOOKUP_NO_CONVERSION so that we don't allow two-level conversions,
+ but don't set it otherwise.
+
+Wed Jul 19 20:32:01 1995 Mike Stump <mrs@cygnus.com>
+
+ * init.c (expand_default_init): Don't allow two-level conversions
+ during construction.
+
+Wed Jul 19 18:06:37 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_headof): The type of dyncasting to a pointer to cv
+ void, should be pointer to cv void.
+
+Wed Jul 19 17:25:43 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_dynamic_cast): Allow casting in const.
+
+Wed Jul 19 16:34:27 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_const_cast): If we are passed error_mark_node,
+ return it.
+
+Wed Jul 19 15:24:48 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * class.c (push_nested_class): Make sure TYPE is non-nil.
+
+ * cvt.c (type_promotes_to): Watch for error_mark_node on the
+ incoming TYPE.
+
+Wed Jul 19 13:23:12 1995 Gerald Baumgartner <gb@alexander.cs.purdue.edu>
+
+ * cp-tree.h (SIGTABLE_VT_OFF_NAME): Renamed from SIGTABLE_OFFSET_NAME.
+ (SIGTABLE_VB_OFF_NAME): New macro.
+ (vt_off_identifier): Renamed from offset_identifier.
+ (vb_off_identifier): Added extern declaration.
+
+ * decl.c (vt_off_identifier): Renamed from offset identifier.
+ (vb_off_identifier): New variable to hold the identifier for the
+ sigtable field vb_off.
+ (init_decl_processing): Initialize vb_off_identifier.
+ Renamed vt_off_identifier from offset_identifier.
+ * sig.c (build_signature_method_call): Renamed offset_identifier and
+ local variable offset to vt_off_identifer and vt_off, respecitively.
+ * sig.c (build_signature_table_constructor): Renamed offset to vt_off.
+
+ * decl.c (init_decl_processing): Add vb_off field to
+ sigtable_entry_type. Reorder fields so that pfn gets properly
+ aligned at a 64 bit boundary on the Alpha.
+ * sig.c (build_signature_table_constructor): Build the constructor
+ according to the new layout. Set the vb_off field to -1 for now.
+
+ * decl.c (init_decl_processing): Align sigtable_entry_type on word
+ boundaries instead of double word boundaries to save space.
+
+Tue Jul 18 16:58:37 1995 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (cp_convert): Always call build_cplus_new for a ctor.
+
+Tue Jul 18 14:24:53 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (opt.component_decl_list): Only forbid private/protected
+ in anonymous unions. We need to make this know when the type is
+ defined for an object, to not give the error.
+
+Mon Jul 17 14:22:44 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (opt.component_decl_list): Don't allow access control
+ as private or protected for union members.
+
+Sun Jul 16 14:01:00 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * lex.c (check_newline): For 'p' case, move goto skipline line to
+ before end brace for 'pragma'.
+
+Fri Jul 7 13:55:58 1995 Mike Stump <mrs@cygnus.com>
+
+ * g++.1: Tiny updates.
+
+Fri Jul 7 13:05:20 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (cp_finish_decl): Only destruct local static variables if
+ they are constructed, and only construct the first time control
+ passes completely through its declaration (if not initialized with a
+ constant-expression).
+ (expand_static_init): Likewise.
+
+Wed Jul 5 14:05:04 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck.c (comptypes, case OFFSET_REF): If either offset basetype
+ is a TEMPLATE_TYPE_PARM, give a match.
+
+Fri Jun 30 15:42:57 1995 Mike Stump <mrs@cygnus.com>
+
+ * method.c (build_overload_value): Handle encoding of null pointer
+ constants (or any pointer with a constant numeric value) for
+ templates.
+
+Fri Jun 30 13:45:51 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c (convert_harshness): Add QUAL_CODE when we're faced with
+ const vs non-const for void conversions.
+
+Fri Jun 30 10:19:52 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_start_all_catch): Fix problem with finding an
+ outer nested try block when there is no code to separate it from an
+ inner try block.
+
+Fri Jun 30 02:22:26 1995 Mike Stump <mrs@cygnus.com>
+
+ * search.c (dfs_pushdecls): Consume 2 or 3 orders of magnitude less
+ memory please when virtual bases are used.
+
+Thu Jun 29 19:03:47 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (build_vbase_path): Avoid testing things that cannot be
+ null to see if they are null.
+ * cvt.c (convert_pointer_to_vbase): Remove code that doesn't work.
+ * decl.c (finish_function): Pass a type into the new
+ convert_pointer_to_vbase instead of a binfo.
+ * search.c (convert_pointer_to_vbase): Rewritten to use get_vbase
+ and convert_pointer_to_real.
+ (expand_indirect_vtbls_init): Use convert_pointer_to_vbase instead
+ of the more cryptic call to get_vbase.
+
+Thu Jun 29 09:35:05 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (BOOL_TYPE_SIZE): Fix broken SLOW_BYTE_ACCESS check.
+
+Thu Jun 29 03:43:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (instantiate_template): Don't strip 'this' twice.
+
+ * pt.c (coerce_template_parms): Allow null pointer constants.
+
+ * decl.c (revert_static_member_fn): But only if DECL_ARGUMENTS is
+ set.
+
+Wed Jun 28 18:39:03 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (revert_static_member_fn): Also remove 'this' from
+ DECL_ARGUMENTS.
+ * decl2.c (check_classfn): Don't revert this function until we get a
+ match.
+
+Wed Jun 28 14:07:27 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (component_decl): Clear PREFIX_ATTRIBUTES here.
+
+Wed Jun 28 11:05:13 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_file): Handle global vector news.
+ * init.c (build_new): Encode vector news so that later we will know
+ how many elements there are.
+
+Mon Jun 26 13:38:06 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * expr.c (cplus_expand_expr): Don't mess with temp slots.
+
+ * decl2.c (warn_if_unknown_interface): Don't crash if tinst_for_decl
+ returns null.
+
+ * decl2.c (check_classfn): Use revert_static_member_fn.
+ * decl.c (revert_static_member_fn): Diagnose static member functions
+ declared const or volatile.
+
+ * decl2.c (grokfield): Check for missing default args here, too.
+ (check_default_args): Function to do the checking.
+ * decl.c (pushdecl): Use it.
+
+ * decl.c (pushdecl): Don't warn about shadowing a member of `this'
+ if there is no `this'.
+
+Sun Jun 25 11:34:25 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Downgrade 'called before definition'
+ to a warning, as it ought to go away after Monterey.
+
+Sat Jun 24 14:18:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (coerce_template_parms): Don't do extra checking on pointer
+ to member arguments.
+
+ * class.c (finish_struct): const and reference members don't prevent
+ a class from being an aggregate.
+
+ * class.c (finish_struct): Signatures are always aggregates.
+
+Fri Jun 23 17:20:29 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (check_classfn): Improve error message.
+
+ * pt.c (tsubst): Handle PROMOTE_PROTOTYPES.
+
+Thu Jun 22 01:50:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (comptypes): Don't ignore method quals.
+
+ * class.c (finish_struct): Non-abstract virtuals are always USED.
+
+ * decl.c (build_ptrmemfunc_type): The underlying union type isn't
+ IS_AGGR_TYPE, either.
+ * class.c (finish_struct): Use CLASSTYPE_NON_AGGREGATE instead.
+ * cp-tree.h: Likewise.
+
+ * cp-tree.h (lang_type): Add aggregate.
+ (CLASSTYPE_AGGREGATE): New macro.
+ (TYPE_NON_AGGREGATE_CLASS): Likewise.
+ * class.c (finish_struct): Determine whether a class is an
+ aggregate.
+ * decl.c (cp_finish_decl): Check TYPE_NON_AGGREGATE_CLASS instead of
+ TYPE_NEEDS_CONSTRUCTING.
+ * typeck2.c (digest_init): Check TYPE_NON_AGGREGATE_CLASS for
+ subobjects, too.
+
+ * pt.c (tsubst, PARM_TYPE): Propagate DECL_ARTIFICIAL.
+
+ * decl.c (start_function): For pre-parsed functions, layout all of
+ the parm decls again.
+ (grokvardecl): TREE_PUBLIC depends on DECL_THIS_EXTERN, not
+ DECL_EXTERNAL.
+
+ * pt.c (coerce_template_parms): Improve checking for invalid
+ template parms.
+
+Wed Jun 21 12:01:16 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Forbid declaration of a static member
+ with the same name as its enclosing class.
+
+Mon Jun 19 10:28:14 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (finish_function): Clear current_class_decl.
+
+ * typeck.c (build_conditional_expr): Use convert (boolean_type_node
+ instead of truthvalue_conversion.
+
+ * class.c (finish_struct): A data member with the same name as the
+ class doesn't suppress constructors.
+
+Fri Jun 16 18:11:39 1995 Gerald Baumgartner <gb@alexander.cs.purdue.edu>
+
+ * decl.c (start_function): If current_class_decl is a signature
+ pointer, don't dereference it but set C_C_D to current_class_decl.
+
+Fri Jun 16 17:06:28 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (duplicate_decls): Complain about virtual functions
+ redeclared to be inline.
+
+Fri Jun 16 13:20:38 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (get_unique_name): New routine to name unnamed namespaces.
+ (push_namespace): Use get_unique_name for naming unnamed namespaces.
+
+Thu Jun 15 15:00:41 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y: Call cplus_decl_attributes with prefix_attributes where
+ appropriate.
+
+Wed Jun 14 19:24:49 1995 Mike Stump <mrs@cygnus.com>
+
+ * search.c (get_vbase): New routine to switch hierarchies from the
+ CLASSTYPE_VBASECLASSES to the normal one.
+ (expand_indirect_vtbls_init): Use get_vbase to figure out how we
+ want to convert to a vbase pointer.
+
+Mon Jun 12 17:50:30 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (instantiate_class_template): Add the new instantiation to
+ template_classes.
+ (do_pending_expansions): Call instantiate_member_templates on all of
+ the classes in template_classes.
+
+Mon Jun 12 12:36:59 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (complete_array_type): Fill in the TYPE_DOMAIN of our
+ TYPE_MAIN_VARIANT if it is not filled in.
+ * init.c (build_delete): If the TYPE_DOMAIN is not set, give an
+ error instead of core dumping.
+
+Mon Jun 12 10:41:40 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (can_convert): Also check for distance > 0.
+ (can_convert_arg): Likewise.
+ (user_harshness): Likewise.
+
+Fri Jun 9 19:17:21 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * g++.c (MATH_LIBRARY): Provide default.
+ (main): Always link with the math library if we link with libstdc++.
+
+ * decl.c (start_function): Complain about redefinition of a function
+ even when the pending_inline version is compiled after the other
+ version.
+
+Thu Jun 8 15:44:38 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * gc.c (build_dynamic_cast): Build up a reference to a parameter of
+ aggregate type.
+
+Wed Jun 7 15:31:57 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (build_vec_delete): Resolve an offset ref before we try to
+ use it.
+
+Wed Jun 7 14:19:32 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_modify_expr): If the class lacks a constructor or
+ assignment operator, return error_mark_node.
+ (common_type): Use build_cplus_array_type.
+
+Tue Jun 6 09:41:27 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (dont_allow_type_definitions): New variable set when types
+ cannot be defined.
+ (finish_struct): Use it.
+ * cp-tree.h (dont_allow_type_definitions): Define it.
+ * parse.y (primary, handler_seq): Set it.
+
+Mon Jun 5 18:49:38 1995 Mike Stump <mrs@cygnus.com>
+
+ * method.c (build_opfncall): Use DECL_CHAIN, not TREE_CHAIN for
+ results from lookup_fnfields. Always give warning/error on bad
+ code.
+
+Mon Jun 5 11:39:37 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (member_init_ok_or_else): Don't allow initialization of
+ an ancestor's member from within a constructor.
+
+Mon Jun 5 11:20:34 1995 Gerald Baumgartner <gb@alexander.cs.purdue.edu>
+
+ * sig.c (build_signature_table_constructor): Use DECL_CONTEXT
+ instead of DECL_CLASS_CONTEXT for calculating the vfield offset so
+ abstract virtual functions are handled correctly.
+
+ * sig.c (build_signature_table_constructor): Store the correct
+ delta in signature table entries. It does not yet work for
+ classes with virtual base classes as implementations of signatures.
+ (build_signature_method_call): Add the delta to the object_ptr
+ before generating the function call.
+
+ * call.c (build_method_call): Make instance_ptr the signature
+ pointer itself instead of dereferencing the optr.
+ * sig.c (build_signature_method_call): Dereference the optr for the
+ direct and virtual calls.
+
+ * sig.c (build_signature_table_constructor): Make the tag for
+ default implementations -1 instead of 2.
+ (build_signature_method_call): Change the generated conditional
+ expression correspondingly.
+
+ * sig.c (build_signature_pointer_constructor): Deleted the sorry
+ message that said we can't handle multiple inheritance for
+ implementations of signatures
+ (build_signature_method_call): Use the offset from the sigtable
+ entry instead of the vptr field from the signature pointer for
+ building a virtual function call.
+
+ * class.c (build_vfn_ref): Deleted signature specific code, we don't
+ call this function anymore from build_signature_method_call.
+
+ * cp-tree.h (SIGNATURE_VPTR_NAME): Deleted. We use the right vptr
+ field in the object now instead of in the signature pointer/ref.
+ (build_vptr_ref): Deleted extern declaration.
+ * sig.c (build_vptr_ref): Deleted.
+ (build_signature_pointer_or_reference_type): Deleted construction of
+ the vptr field.
+ (build_signature_pointer_constructor): Deleted initialization of/
+ assignment to the vptr field.
+
+ * sig.c (build_signature_table_constructor): Convert the signature
+ table entry fields to their correct types.
+
+ * sig.c (build_signature_table_constructor): Don't call digest_init
+ for the fields of a sigtable entry, it's wasted time.
+
+ * sig.c (build_signature_table_constructor): Correctly set the
+ offset and index fields of a sigtable entry. Build the constructor
+ the way digest_init does, digest_init can't handle initializing an
+ anonymous union inside a struct.
+ (build_signature_method_call): Use the index field instead of the
+ delta field to get the vtable index.
+
+ * decl.c (init_decl_processing): Fix number of fields for building
+ sigtable_entry_type.
+
+ * cp-tree.h (tag_identifier, offset_identifier): Added extern decls.
+ (SIGTABLE_CODE_NAME): Renamed to SIGTABLE_TAG_NAME.
+ (SIGTABLE_PFN_NAME): Deleted, we'll use VTABLE_PFN_NAME instead.
+ * decl.c (tag_identifier, offset_identifier): New variables to
+ hold the identifiers for the sigtable fields tag and offset.
+ (init_decl_processing): Initialize these variables.
+ (init_decl_processing): Use these variables to build the
+ sigtable_entry_type structure. Rename the code and offset fields
+ to tag and delta, respectively; add offset and index fields. Changed
+ types of fields from short_integer_type_node to delta_type_node.
+ * sig.c (build_signature_table_constructor): Rename code and offset
+ to tag and delta, respectively.
+ (build_signature_method_call): Likewise. Use above variables.
+
+Thu Jun 1 17:03:51 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (lookup_name_real): Don't try to look anything up in an
+ erroneous object.
+
+Fri Jun 2 10:30:14 1995 Mike Stump <mrs@cygnus.com>
+
+ * method.c (build_overload_int): New routine. Break out
+ functionality from build_overload_value so we can reuse it.
+ (build_overload_value): Handle pointer to member functions as value
+ parameters for templates.
+ (build_overload_identifier): Since template parameters are shared
+ among all instantiations, we have to substitute in the real types
+ in TREE_TYPE (parm).
+ pt.c (coerce_template_parms): Likewise.
+ (push_template_decls): Likewise.
+ (grok_template_type): Deleted as template parameters are shared
+ among all instantiations.
+
+Wed May 31 19:10:32 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (grokdeclarator): Always give errors on constant overflow
+ for array indices.
+
+Wed May 31 11:39:43 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (commonparms): Don't abort if simple_cst_equal returns < 0.
+ (build_c_cast): Don't tack on a NON_LVALUE_EXPR when casting to
+ reference type.
+ (build_indirect_ref): Fix check for *&.
+
+Fri Jun 16 06:54:03 1995 Mike Stump <mrs@cygnus.com>
+
+ * Version 2.7.0 released.
+
+Fri Jun 16 15:07:29 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (DEMANGLER_PROG): Add LIBS.
+
+Thu Jun 15 15:00:41 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (define_function): Don't set DECL_INTERFACE_KNOWN.
+
+Wed Jun 7 20:00:31 1995 Mike Stump <mrs@cygnus.com>
+
+ * *.[chy]: Change all callers of finish_decl to cp_finish_decl.
+ * decl.c (finish_decl): New routine to handle call backs from the
+ mid end (declare_hidden_char_array).
+
+Wed Jun 7 19:02:50 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (start_function): Handle setting C_C_D here.
+ (set_C_C_D): Removed.
+ (struct saved_scope): Remove class_decl.
+ (push_to_top_level): Don't save current_class_decl.
+ (pop_from_top_level): Don't restore current_class_decl or C_C_D.
+ (struct cp_function): Add C_C_D.
+ (push_cp_function_context): Save C_C_D.
+ (pop_cp_function_context): Restore C_C_D.
+
+Fri Jun 2 11:05:58 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (set_C_C_D): New function. suspend_momentary before
+ building C_C_D.
+ (pop_from_top_level): Call it.
+ (start_function): Likewise.
+ (pop_cp_function_context): Likewise.
+
+ * class.c, cp-tree.h, decl.c, decl2.c, parse.y: Lose all references
+ to current_vtable_decl, CLASSTYPE_INST_VAR and CLASSTYPE_VTBL_PTR.
+
+ * decl.c (push_cp_function_context): Save current_class_decl.
+ (pop_cp_function_context): Restore current_class_decl and set C_C_D.
+ (pop_from_top_level): Don't use CLASSTYPE_INST_VAR to set C_C_D.
+ (start_function): Likewise.
+
+ * class.c (popclass): Don't mess with current_class_decl,
+ current_vtable_decl, or C_C_D.
+
+Mon May 29 12:45:10 1995 Paul Eggert <eggert@twinsun.com>
+
+ * Make-lang.in (c++.mostlyclean): Remove $(DEMANGLER_PROG).
+
+Wed May 24 15:55:18 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (duplicate_decls): Check simple_cst_equal result against 0.
+ * decl2.c (finish_anon_union): Likewise.
+ * method.c (largest_union_member): Likewise.
+
+Wed May 24 14:41:11 1995 H.J. Lu <hjl@nynexst.com>
+
+ * Make-lang.in (cxxmain.o): Replace single quotes with backslashes.
+
+Mon May 22 17:38:48 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (g++, g++-cross, cc1plus, DEMANGLER_PROG):
+ Use $@ instead of output name so works even if have .exe.
+ (cxxmain.o): Use cp if ln -s fails.
+ (c++.install-man): Use $(exeext) in executable names.
+ (c++.mostlyclean, stage[1-4]): Use $(objext) in object file names.
+ * Makefile.in (../cc1plus): Use $(exeext) in name of executable.
+
+Wed May 24 01:39:03 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): parms can be null, duh.
+
+Tue May 23 01:32:09 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): If convert_arguments failed, just bail.
+
+Fri May 19 10:31:11 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (convert_force): Pass LOOKUP_NORMAL to cp_convert.
+
+ * tree.c (copy_to_permanent): Oops.
+
+Fri May 19 10:01:07 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (break_out_target_exprs): Add decl.
+
+Thu May 18 13:02:30 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (start_function): Move *all* interface handling stuff after
+ the pushdecl.
+
+ * tree.c (mapcar): Renamed from make_deep_copy and generalized.
+ (perm_manip): Return t if permanent, otherwise 0.
+ (copy_to_permanent): Use them.
+ (bot_manip): Helper for break_out_target_exprs.
+ (break_out_target_exprs): New function. Uses mapcar.
+
+ * typeck.c (convert_arguments): Use it.
+
+ * method.c (hack_identifier): Use convert_from_reference to
+ dereference a reference.
+
+Wed May 17 17:54:54 1995 Mike Stump <mrs@cygnus.com>
+
+ * call.c (convert_harshness): Move reference bashing before pointer
+ to member bashing.
+
+Wed May 17 16:57:53 1995 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (convert_to_reference): Only complain, if complaints are
+ wanted.
+ * typeck.c (build_function_call_real): Likewise. If
+ LOOKUP_SPECULATIVELY is set and something won't work, return
+ NULL_TREE.
+ * cvt.c (cp_convert): Likewise. Pass flags down to build_method_call.
+ (convert): Pass LOOKUP_NORMAL to cp_convert.
+ * typeck.c (convert_for_assignment): Likewise.
+ (convert_force): Pass LOOKUP_COMPLAIN to cp_convert.
+ (convert_arguments): Get out early if we get an error_mark_node.
+ (convert_for_initialization): Use cp_convert instead of convert so
+ that we can pass flags down.
+ * cp-tree.h (LOOKUP_SPECULATIVELY): Added documentation.
+
+Wed May 17 01:43:58 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck2.c (store_init_value): Don't take the MAIN_VARIANT of the
+ decl type.
+
+ * class.c (finish_struct): Don't complain about a class with no
+ user-defined constructors but with a member that has no default
+ constructor, as this is OK for aggregates.
+
+ * expr.c (cplus_expand_expr, NEW_EXPR): If this is an explicit
+ constructor call, mark slot addressable.
+
+Tue May 16 18:37:51 1995 Douglas Rupp <drupp@cs.washington.edu>
+
+ * g++.c: Changed WINNT to _WIN32.
+
+Tue May 16 12:40:16 1995 Jason Merrill <jason@lisa.cygnus.com>
+
+ * lex.c (handle_sysv_pragma): Don't use token_buffer.
+
+Tue May 16 12:05:26 1995 Mike Stump <mrs@cygnus.com>
+
+ * call.c (resolve_scope_to_name): Add initial semantic support for
+ namespaces.
+ * class.c (finish_struct): Likewise.
+ * cp-tree.h (NAMESPACE_LEVEL): Likewise.
+ * cvt.c (build_up_reference, convert_to_reference): Likewise.
+ * decl.c (binding_level::namespace_p, suspend_binding_level): Likewise.
+ (resume_binding_level, toplevel_bindings_p): Likewise
+ (namespace_bindings_p, declare_namespace_level): Likewise.
+ (resume_level, push_namespace, pop_namespace): Likewise.
+ (pop_everything, pushtag, duplicate_decls, pushdecl): Likewise.
+ (implicitly_declare, lookup_namespace_name): Likewise.
+ (lookup_name_real, start_decl, make_temporary_for_reference): Likewise.
+ (obscure_complex_init, finish_decl, expand_static_init): Likewise.
+ (grokvardecl, grokdeclarator, parmlist_is_exprlist): Likewise.
+ (store_parm_decls, hack_incomplete_structures): Likewise.
+ * decl2.c (get_temp_name, finish_anon_union): Likewise.
+ (current_namespace, push_namespace, pop_namespace): Likewise.
+ (do_namespace_alias, do_toplevel_using_decl): Likewise.
+ (do_class_using_decl): Likewise.
+ * error.c (dump_decl): Likewise.
+ * init.c (build_member_call, build_offset_ref): Likewise.
+ * lex.c (identifier_type): Likewise.
+ * parse.y (lang_extdef, using_decl, extdef): Likewise.
+ (component_decl_1, nested_name_specifier_1): Likewise.
+ * spew.c (yylex): Likewise.
+ * tree.def (NAMESPACE_DECL): Likewise.
+
+Tue May 16 11:55:35 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (push_overloaded_decl): Return the new decl even if it
+ can't be pushed.
+
+Tue May 16 11:00:37 1995 Jason Merrill <jason@lisa.cygnus.com>
+
+ * typeck.c (decay_conversion): Split out from default_conversion.
+ (default_conversion): Call it.
+ (build_binary_op): Likewise.
+ (build_binary_op_nodefault): Use decay_conversion for truth ops.
+
+Mon May 15 12:47:56 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (warn_extern_redeclared_static): This is a pedwarn.
+ (duplicate_decls): Always use the old decl's linkage info. Don't
+ play with linkage of consts.
+ (pushdecl): Don't play with linkage of consts.
+ (redeclaration_error_message): Don't complain about an old public
+ decl and a new non-public decl here.
+ (grokvardecl): Handle linkage of consts here.
+ (grokdeclarator): An 'extern inline' is public. Pass constp to
+ grokvardecl.
+ (start_function): Wait until after the pushdecl to do some linkage
+ stuff.
+
+ * decl2.c (import_export_vtable): Make duplicates weak rather than
+ static if supported.
+ (import_export_inline): Likewise.
+ * pt.c (do_pending_expansions): Likewise.
+
+ * class.c (build_vbase_path): flag_assume_nonnull_objects only
+ affects reference conversion.
+
+ * init.c (emit_base_init): Build up an RTL_EXPR and add it to
+ rtl_expr_chain.
+ * decl.c, decl2.c: s/base_init_insns/base_init_expr/.
+
+Tue May 16 07:06:28 1995 Paul Eggert <eggert@twinsun.com>
+
+ * method.c (numeric_output_need_bar): Renamed from misspelling.
+
+ * typeck.c (build_ptrmemfunc): Fix misspellings in messages.
+
+Sun May 14 10:26:22 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * lang-options.h, lang-specs.h: New files.
+
+Thu May 11 00:31:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (default_conversion): Don't check for BLKmode before
+ pulling out the decl_constant_value.
+
+ * decl.c (start_function): Clear named_labels and shadowed_labels.
+
+ * typeck.c (build_function_call_real): Also synthesize methods here.
+
+Wed May 10 00:55:59 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (finish_file): Synthesize exported methods before the
+ reconsider loop.
+
+ * parse.y: Move declaration of flag_new_for_scope to file scope.
+
+Tue May 9 19:10:33 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c: Add flag_new_for_scope for new -ffor-scope flag.
+ * parse.y (FOR): Conditionalize the pushing and poping of scope for
+ the for-init-statement upon the new flag_new_for_scope.
+ * parse.y (try_block): Simplify and use compstmt.
+
+Mon May 8 12:41:52 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (define_function): Mark function decl artificial.
+
+Sun May 7 00:51:28 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y (simple_stmt, FOR): Put back push/pop for condition scope.
+
+ * decl2.c (grokclassfn): DECLs don't have cv-qualified types.
+ * tree.c (build_cplus_method_type): Likewise.
+
+ * cp-tree.h (SET_DECL_ARTIFICIAL): Just set DECL_ARTIFICIAL to 1.
+
+ * typeck.c (build_function_call_real): If convert_arguments failed,
+ just bail.
+ (convert_arguments): If one of the arguments is error_mark_node,
+ just bail.
+
+Sat May 6 02:39:41 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (duplicate_decls): Don't check DECL_NOT_REALLY_EXTERN for
+ decls that don't include it.
+
+Fri May 5 14:23:30 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (duplicate_decls): Decls that have DECL_INTERFACE_KNOWN or
+ DECL_NOT_REALLY_EXTERN set aren't extern decls.
+
+ * typeck.c (build_indirect_ref): Don't call default_conversion for a
+ parameter of reference_type.
+ * cvt.c (convert_from_reference): Just use build_indirect_ref.
+
+ * pt.c (do_type_instantiation): Only instantiate member functions
+ that actually come from templates.
+
+Fri May 5 09:46:05 1995 Mike Stump <mrs@cygnus.com>
+
+ * parse.y: Generalized cleanup of poplevels, and compound statements
+ and compound statements in try blocks. Rewritten `for' rule so that
+ the scope of variables declared in the for clause is shortened to
+ span just to the end of the statement, instead of the whole
+ containing block.
+
+Fri May 5 00:37:14 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (convert_harshness): Handle pointers to members better.
+
+Thu May 4 16:00:26 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (delete_sanity): Do access control here.
+ * init.c (build_delete): Instead of here.
+
+ * Make-lang.in: Build c++filt.
+
+Wed May 3 02:59:53 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (cplus_decl_attributes): If we just modified a TYPE_DECL,
+ update our IDENTIFIER_TYPE_VALUE.
+
+Fri Apr 28 07:58:41 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * lex.c (cons_up_default_function): Fix linkage of #pragma
+ implemented functions.
+
+Thu Apr 27 16:56:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (build_overload_name): Simplify and fix repeated type
+ folding.
+
+ * decl.c (grokdeclarator): Prohibit pointers to void or reference
+ members.
+
+Thu Apr 27 09:49:07 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck2.c (process_init_constructor): Make sure initializers are
+ fully digested.
+
+Thu Apr 27 01:11:55 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * lex.c (cons_up_default_function): Always defer synthesis.
+
+Thu Apr 27 00:20:37 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (mark_inline_for_output): Don't play with pending_inline
+ stuff.
+
+Wed Apr 26 17:48:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (user_harshness): New function; like build_type_conversion,
+ but doesn't actually build anything.
+ (compute_conversion_costs): Use it instead of build_type_conversion.
+
+Wed Apr 26 17:11:25 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_function_call_real): Improve error message for
+ calling a non-function.
+
+ * method.c (hack_identifier): Lose check for calling a data member.
+
+Wed Apr 26 16:59:13 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck2.c (build_functional_cast): Remove very old cruft.
+ Seems like good code is generated without it.
+
+Wed Apr 26 00:47:16 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (do_build_assign_ref): Fix handling of anonymous unions.
+ (do_build_copy_constructor): Likewise.
+
+ * parse.y (simple_stmt, SWITCH): Call {push,pop}_switch.
+
+ * decl.c (push_switch): New function.
+ (pop_switch): Likewise.
+ (define_case_label): Check for jumping over initialization.
+
+ * call.c (build_method_call): Check for an inline function being
+ called before its definition has been seen.
+ * typeck.c (build_function_call_real): Likewise.
+
+ * decl.c (duplicate_decls): Check for a function being redeclared
+ inline after its address has been taken.
+
+ * typeck.c (build_conditional_expr): Handle related class lvalues.
+
+Tue Apr 25 13:20:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (do_pending_expansions): Don't expand unused templates.
+
+ * parse.y (component_decl): Accept a lone semicolon.
+
+Tue Apr 25 00:25:56 1995 Jason Merrill <jason@rtl.cygnus.com>
+
+ * call.c (build_method_call): Don't allow an RTL_EXPR to serve as the
+ object parameter anymore.
+
+ * expr.c (cplus_expand_expr): Don't create RTL_EXPRs with no insns.
+
+Mon Apr 24 12:35:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y (simple_stmt, decl case): Clear prefix_attributes.
+ (lang_extdef): Likewise.
+
+ * parse.y (maybe_parmlist): New rule for use in declarators where
+ this could either be a list of expressions or parameters. Calls
+ suspend_momentary before deciding which.
+ (direct_after_type_declarator): Use it.
+ (complex_direct_notype_declarator): Use it.
+
+ * pt.c (tsubst): Propagate attributes const and noreturn.
+
+ * typeck.c (build_modify_expr): If warn_synth, call build_opfncall
+ before doing the default thing.
+
+Thu Apr 27 21:49:36 1995 Doug Evans <dje@cygnus.com>
+
+ * typeck.c (common_type): Call lookup_attribute instead of
+ value_member.
+
+Tue Apr 25 18:07:43 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in: Change "realclean" to "maintainer-clean".
+
+Sun Apr 23 12:32:38 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_file): Fix broken linked list handling.
+
+Fri Apr 21 18:08:43 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (finish_base_struct): Don't set TYPE_HAS_COMPLEX_*_REF
+ as often.
+ (finish_struct): Likewise.
+
+ * various: Use TYPE_HAS_TRIVIAL_* instead of TYPE_HAS_COMPLEX_*.
+
+ * cp-tree.h (TYPE_HAS_TRIVIAL_INIT_REF): New macro.
+ (TYPE_HAS_TRIVIAL_ASSIGN_REF): New macro.
+
+Fri Apr 21 15:52:22 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * typeck.c (c_expand_return): Only expand a returned TARGET_EXPR if
+ it is of the same type as the return value.
+
+Fri Apr 21 03:01:46 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (finish_file): Reconsider if synthesizing a method wrote
+ out its assembly.
+
+ * typeck.c (convert_for_initialization): Don't call a trivial copy
+ constructor.
+
+ * typeck2.c (store_init_value): Only abort if the type has a
+ non-trivial copy constructor.
+
+ * typeck.c (c_expand_return): If we're returning in a register and
+ the return value is a TARGET_EXPR, expand it. Only do
+ expand_aggr_init if we're returning in memory.
+ (expand_target_expr): Function to expand a TARGET_EXPR.
+ (build_modify_expr): Use it.
+
+ * tree.c (build_cplus_new): Layout the slot.
+
+ * expr.c (cplus_expand_expr): Use expand_call to expand the call
+ under a NEW_EXPR, so the target is not discarded.
+
+Thu Apr 20 14:59:31 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_dynamic_cast): Tighten error checking.
+
+Thu Apr 20 11:23:54 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * expr.c (cplus_expand_expr): Only abort if the returned target is
+ different from what we expected if the type has a non-trivial copy
+ constructor.
+
+ * decl2.c (cplus_decl_attributes): Attributes applied to a template
+ really apply to the template's result.
+
+ * tree.c (lvalue_p): Check IS_AGGR_TYPE instead of TREE_ADDRESSABLE
+ to decide whether to consider a CALL_EXPR an lvalue.
+
+ * class.c (finish_struct_bits): Only set TREE_ADDRESSABLE if the
+ type has a non-trivial copy constructor.
+
+ * decl.c (start_function): If interface_known, unset
+ DECL_NOT_REALLY_EXTERN on the function.
+
+Wed Apr 19 16:53:13 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (do_function_instantiation): Handle explicit instantiation of
+ member functions.
+ (do_type_instantiation): Handle 'inline template class foo<int>',
+ meaning just spit out the vtable.
+
+ * lex.c (cons_up_default_function): Set DECL_NOT_REALLY_EXTERN on
+ the consed functions.
+
+ * decl2.c (import_export_inline): Set DECL_INTERFACE_KNOWN.
+
+Wed Apr 19 16:28:17 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c, class.c, decl2.c, gc.c, init.c, parse.y, pt.c, search.c,
+ typeck.c: Include output.h.
+
+Wed Apr 19 14:57:21 1995 Gerald Baumgartner <gb@alexander.cs.purdue.edu>
+
+ * call.c (build_method_call): Allow a signature member functions to
+ be called from a default implementation.
+
+Wed Apr 19 10:21:17 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * repo.c (finish_repo): Remember what directory we are in.
+
+ * search.c (expand_upcast_fixups): Don't mess with abort_fndecl.
+
+ * repo.c: Use obstacks instead of fixed-size buffers. Don't spit
+ out the second copy of the symbol name. Don't remember COLLECT_GCC.
+
+Wed Apr 19 02:32:40 1995 Mike Stump <mrs@cygnus.com>
+
+ * search.c (virtual_context): New function to get the virtual
+ context of a function.
+ (expand_upcast_fixups): New function to generate runtime vtables.
+ (fixup_virtual_upcast_offsets): Likewise.
+ (expand_indirect_vtbls_init): Use fixup_virtual_upcast_offsets to
+ ensure that the this offsets for upcasts from virtual bases into
+ other virtual bases or non-virtual bases are correct at construction
+ time and destruction time.
+ * class.c (fixup_vtable_deltas): Modify to fixup all offsets in all
+ vtables in all virtual bases, instead of just one vtable in each
+ virtual base.
+ (fixup_vtable_deltas1): Likewise.
+
+Tue Apr 18 03:57:35 1995 Michael Meissner <meissner@cygnus.com>
+
+ * Makefile.in (lex.o): Add dependency on c-pragma.h.
+
+ * lex.c (handle_sysv_pragma): Use NULL_PTR and NULL_TREE as
+ appropriate, instead of 0.
+
+Mon Apr 17 12:28:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (pushdecl): Use decls_match, not duplicate_decls, for
+ comparing local and global decls.
+
+Fri Apr 14 01:46:52 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (convert_arguments): Only prohibit passing to ... of
+ types with non-trivial copy constructors.
+
+ * repo.c (repo_template_used): Don't try to mess with no id.
+
+Fri Apr 14 23:32:50 1995 Per Bothner <bothner@rtl.cygnus.com>
+
+ * decl.c (duplicate_decls): Use cp_warning_at for redundant-decls.
+
+Thu Apr 13 15:37:42 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (current_tinst_level): Delete declaration, since it's
+ static inside pt.c.
+
+ * typeck.c (build_modify_expr): Catch incompatible array assignment.
+
+ * parse.y (attribute_list, attrib): Rewrite actions to feed the
+ right stuff to decl_attributes.
+
+Thu Apr 13 11:24:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * search.c (dfs_debug_mark): Check for magic virtual like
+ import_export_vtable.
+
+ * typeck.c (build_binary_op_nodefault): Don't call cp_pedwarn with
+ four args.
+
+Wed Apr 12 12:02:57 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (finish_file): Move prevtable pass before needs_messing_up
+ decision.
+
+Tue Apr 11 11:20:27 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (finish_decl): If we're writing out a static data member of
+ a class, we want the debug info for that class.
+
+ * gc.c (build_t_desc): Check linkage of a class properly.
+
+ * class.c (finish_struct): Set the 'headof' offset for the main
+ vtable properly.
+ (prepare_fresh_vtable): Fix typeinfo pointer here.
+ (modify_one_vtable): Instead of here.
+
+Mon Apr 10 12:15:59 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * repo.c (repo_get_id): New function to return the interesting
+ identifier for a repo entity.
+ (repo_template_used): Use it.
+ (repo_template_instantiated): Mark the id as chosen.
+ (init_repo): Record whether or not the id was chosen.
+ (finish_repo): Note if an id was newly chosen.
+
+ * pt.c (do_function_instantiation): Call repo_template_instantiated.
+ (do_type_instantiation): Likewise. Don't diagnose multiple
+ instantiation.
+
+ * decl2.c (finish_file): Use DECL_NOT_REALLY_EXTERN when deciding
+ whether or not to synthesize a method.
+
+ Undo these changes:
+ * class.c (finish_vtbls): build more vtables if flag_rtti is on.
+ * class.c (modify_all_direct_vtables): ditto.
+ * init.c (expand_direct_vtbls_init): expand more vtables if
+ flag_rtti is on.
+
+Sat Apr 8 17:45:41 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_headof): Use ptrdiff_type_node instead of
+ integer_type_node on pointer arithmetic.
+
+Sat Apr 8 11:57:04 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_modify_expr): Undo previous change.
+
+Thu Apr 6 01:23:50 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * Makefile.in (compiler): Remove ../cc1plus before rebuilding it.
+
+ * repo.c (get_base_filename): Put the .rpo file in the directory
+ with the object file, not the source.
+
+ * typeck.c (build_conditional_expr): Handle pmf's better.
+
+ * repo.c (finish_repo): Also use ASM_OUTPUT_LABELREF to print out
+ the name of the symbol.
+
+Wed Apr 5 15:24:12 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * repo.c (open_repo_file): Make repo filename DOS-compliant.
+ (*): Also write a new repo file if some previously-used
+ templates are no longer used. Only remember the identifier.
+
+ * lex.c (cons_up_default_function): If this function belongs to a
+ template class, call repo_template_used for it.
+
+ * repo.c (repo_template_used): Using a class means using its vtable,
+ if any.
+ (finish_repo): Likewise.
+
+ * typeck.c (build_modify_expr): Only wrap TARGET_EXPRs in RTL_EXPRs
+ if the type has a complex copy constructor.
+
+ * decl2.c (lang_decode_option): -frepo implies
+ -fno-implicit-templates.
+
+ * decl.c (start_function): Clear current_{base,member}_init_list.
+
+ * lex.c (init_lex): Also unset *_eq if ! flag_operator_names.
+
+Tue Apr 4 16:11:08 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (struct cp_function): Add {base,member}_init_list.
+ (push_cp_function_context): Save current_{base,member}_init_list.
+ (pop_cp_function_context): Restore them.
+
+Mon Apr 3 16:55:08 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * repo.c (get_base_filename): Take filename parm, fix logic bug.
+
+ * typeck.c (build_compound_expr): Do not warn about a compound expr
+ in which the first expression has no side effects.
+ (build_x_compound_expr): Warn here instead.
+ (build_conditional_expr): Don't warn about a conditional expression
+ between an enum and the type it promotes to.
+
+ * init.c (build_new): Handle initialization of arrays of builtins
+ properly.
+
+Mon Apr 3 15:08:04 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * repo.c: Include config.h to get definitions of bcopy and rindex
+ on systems that don't have them (e.g., SVR4).
+
+Mon Apr 3 14:41:55 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_table): Pass NULL_TREE instead of init to
+ finish_decl so that it won't try and do error checking on the
+ initializer.
+
+Mon Apr 3 10:45:50 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * repo.c (get_base_filename): Analyze COLLECT_GCC_OPTIONS to
+ determine whether this compile used -c -o.
+ (open_repo_file): Use get_base_filename. Remove the extension.
+ (finish_repo): Spit out the values of main_input_filename,
+ COLLECT_GCC and COLLECT_GCC_OPTIONS.
+
+ * parse.y (structsp): Add TYPENAME_KEYWORD complex_type_name.
+
+Sun Apr 2 23:43:51 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * search.c (compute_access): Don't try to do access control on
+ nested types.
+
+Fri Mar 31 10:14:23 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * repo.c: New file to handle things repo.
+
+ * pt.c (instantiate_template): Call repo_template_used if the
+ definition is accessible.
+ (mark_function_instantiated): Split out from
+ do_function_instantiation.
+ (mark_class_instantiated): Split out from do_type_instantiation.
+
+ * parse.y (template_instantiate_once): Call repo_template_used.
+
+ * lex.c (lang_init): Call init_repo.
+
+ * decl2.c: Handle flag_use_repository.
+ (finish_file): Call finish_repo.
+
+ * decl.c (start_method): Call repo_template_used if this is a
+ template method.
+
+ * Makefile.in (CXX_OBJS): Add repo.o.
+ (repo.o): Add dependencies.
+
+ * Make-lang.in (CXX_SRCS): Add repo.c.
+
+ * decl.c (start_function): If DECL_INTERFACE_KNOWN and
+ DECL_NOT_REALLY_EXTERN are both set, unset DECL_EXTERNAL.
+
+ * typeck.c (build_binary_op_nodefault): Identify the invalid operand
+ types used.
+
+ * decl.c (duplicate_decls): Propagate DECL_NOT_REALLY_EXTERN.
+
+Thu Mar 30 17:54:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Tidy up use of build_type
+ and result_type. When checking for comparison between signed
+ and unsigned, use result_type rather than the (possibly shortened)
+ type of op0. Also, don't warn about equality comparison of a
+ signed operand to an unsigned constant that fits in the signed
+ type.
+
+ * method.c (do_build_copy_constructor): Reverse
+ current_base_init_list after we've built it up.
+
+Thu Mar 30 14:35:18 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (build_throw): Never warn about the value of throw not
+ being used.
+
+Thu Mar 30 13:16:54 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_start_catch_block): Check for bad catch parameter
+ declarations.
+
+Thu Mar 30 13:06:11 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (finish_function): Only set DECL_NOT_REALLY_EXTERN if
+ DECL_EXTERNAL is not already set.
+
+Thu Mar 30 11:26:24 1995 Mike Stump <mrs@cygnus.com>
+
+ * method.c (emit_thunk): Let poplevel know that the last level is
+ for a function so it can create a BLOCK_NODE and set DECL_INITIAL.
+
+Thu Mar 30 11:15:06 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (import_export_inline): Don't set DECL_NOT_REALLY_EXTERN
+ here.
+
+ * decl.c (grokdeclarator): OK, don't abort if we see a decl with
+ METHOD_TYPE.
+ (finish_function): Set DECL_EXTERNAL and DECL_NOT_REALLY_EXTERN on
+ all deferred inlines.
+
+Wed Mar 29 19:35:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cp-tree.h (DECL_THIS_INLINE): New macro.
+ (DECL_NOT_REALLY_EXTERN): New macro.
+ (DECL_THIS_STATIC): New macro.
+
+ * decl.c: Lose all references to current_extern_inline. Break
+ inline semantics into DECL_INLINE for actual inlining and
+ DECL_THIS_INLINE for the linkage wierdness. Use DECL_THIS_STATIC.
+ * decl2.c: Use DECL_NOT_REALLY_EXTERN to indicate that we want to
+ emit an inline here. Associated changes.
+ * lex.c: Likewise.
+ * pt.c: Likewise.
+ * typeck.c: Likewise.
+
+ * call.c (build_method_call): Don't bother trying to handle inlines
+ specially.
+ * cvt.c (convert_to_aggr): Likewise.
+
+ * pt.c (do_function_instantiation): Handle instantiation of
+ public inlines, too.
+
+Wed Mar 29 16:04:25 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (init_exception_processing): Change the interface for
+ __throw_type_match and add decl for new rtti matching routine
+ __throw_type_match_rtti.
+ (build_eh_type): New routine to build a run time descriptor for the
+ expression given.
+ (expand_start_catch_block): Update to use new calling convention for
+ the matcher.
+ (expand_throw): Update to use build_eh_type.
+
+Mon Mar 27 07:14:33 1995 Warner Losh <imp@village.org>
+
+ * g++.c: Removed __NetBSD__ from conditional.
+ Declare strerror if HAVE_STRERROR is defined; otherwise
+ declare sys_errlist and sys_nerr.
+ (my_strerror): New function.
+
+Tue Mar 28 14:16:35 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * search.c (get_binfo): Don't try to be so clever.
+
+ * tree.c (copy_to_permanent): Also suspend_momentary().
+
+ * cvt.c (cp_convert_to_pointer): Hand off to convert_fn_pointer even
+ if the types are the same.
+
+ * decl.c (start_function): Handle extern inlines more like C++ says
+ we should.
+
+ * init.c (build_member_call): Hand constructor calls off to
+ build_functional_cast.
+
+ * typeck2.c (build_functional_cast): Use DECL_NESTED_TYPENAME to get
+ the name of the type.
+
+Tue Mar 28 13:13:56 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Check for the decl returned by
+ grokfndecl to be null before using build_decl_attribute_variant.
+
+Mon Mar 27 18:04:41 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (build_new): Use build_pointer_type instead of
+ TYPE_POINTER_TO.
+
+Fri Mar 24 12:11:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_conditional_expr): Handle pmfs.
+ (convert_for_assignment): Fix pmf support.
+
+ * cvt.c (convert_fn_ptr): Support !flag_vtable_thunks.
+ (cp_convert_to_pointer): Handle pmfs.
+ (cp_convert): Pass pmfs to cp_convert_to_pointer.
+
+ * typeck.c (common_type): Handle inheritance for pmfs.
+
+ * typeck2.c (build_m_component_ref): Do access control.
+
+ * typeck.c (comp_target_types): Check for conversion to void *
+ before checking trickier conversions.
+
+ * decl.c (duplicate_decls): Propagate DECL_ABSTRACT_VIRTUAL_P.
+
+ * pt.c (push_tinst_level): Complain if template instantiation depth
+ is greater than max_tinst_depth.
+
+ * typeck.c (common_type): Assume that we can call common_type to
+ unify the target type of a pointer.
+
+Thu Mar 23 00:48:44 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (finish_file): Don't synthesize methods at
+ finish_vtable_prevardecl time. Do synthesize methods that are not
+ used, but are public and not external.
+
+ * cvt.c (build_type_conversion): Only give an error if for_sure.
+
+ * typeck.c (comp_target_types): Only support pointer conversions if
+ nptrs > 0.
+
+Wed Mar 22 19:30:15 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (build_new): Catch use of an initializer list where it
+ shouldn't be.
+
+Wed Mar 22 16:21:07 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_new): Wrap alloc_expr in an RTL_EXPR if nelts is
+ non-constant.
+
+ * decl2.c: temp_name_counter is now public.
+
+ * decl.c (struct cp_function): Add temp_name_counter field.
+ (push_cp_function_context): Save it.
+ (pop_cp_function_context): Restore it.
+
+ * typeck.c (common_type): Handle unifying function types, and unify
+ unmatched things to void* with a compiler_error, rather than
+ silently like before.
+
+Wed Mar 22 15:10:34 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_prevtable_vardecl, finish_vtable_vardecl): Revert
+ Brendan's last change and fix latent problem that causes TD entries
+ to not come out when the things that need them has yet to be
+ expanded.
+
+Wed Mar 22 15:12:00 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault, comparison ops): Update type0
+ and type1, since we might have changed op0 or op1.
+
+Wed Mar 22 13:33:45 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * typeck.c (common_type): Don't mess up templates.
+
+Wed Mar 22 04:56:00 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (common_type): Handle ptms properly. Also handle
+ T* -> void*.
+ (build_binary_op_nodefault): New variable build_type controls what
+ type is given to the expression when it is created. Set this to
+ boolean_type_node for comparison ops instead of using result_type.
+ (comp_target_types): Allow T * -> void *.
+
+ * cvt.c (cp_convert_to_pointer): Do access control when converting
+ ptms, too.
+
+Tue Mar 21 17:25:06 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (extern_lang_string): Catch use of linkage specs that
+ aren't all naming the same language.
+
+ * class.c (finish_struct): Delete accidental duplicate code.
+
+Tue Mar 21 14:00:57 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Disable pedwarns about
+ comparing functions and incomplete types.
+
+ * decl.c (finish_function): Only unset current_function_decl if
+ !nested.
+ (duplicate_decls): Last change went too far; we only want to stop
+ checking for value/reference ambiguity.
+
+Tue Mar 21 01:26:39 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_generic_desc): Zap the DECL_SIZE so that we can lay it
+ out fresh, as the new type may be larger.
+
+Mon Mar 20 19:01:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * expr.c (extract_init): Try to expand the RTL for the
+ initialization and figure out what it will look like so we can avoid
+ run-time initialization. Disabled for now.
+ (extract_scalar_init): Helper for scalar initialization.
+ (extract_aggr_init): Helper for aggregate initialization.
+
+ * decl.c (duplicate_decls): Don't complain about ambiguous
+ declarations.
+ (obscure_complex_init): Now returns a tree. Call extract_init if
+ we're optimizing and this is a toplevel decl.
+ (finish_decl): Update accordingly.
+
+ * lex.c (check_newline): If we're just changing files (not pushing
+ or popping), update input_file_stack->name.
+
+Mon Mar 20 17:55:04 1995 Mike Stump <mrs@cygnus.com>
+
+ * pt.c (type_unification): Only TEMPLATE_DECLs are handled right now
+ in the transitive unification code.
+
+Mon Mar 20 16:07:50 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (shadow_tag): Don't allow inline, virtual, or explicit on
+ non-functions.
+ (grokdeclarator): Don't allow friends to be defined in local classes.
+
+Sat Mar 18 04:03:33 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (finish_prevtable_vardecl): Use DECL_DECLARED_STATIC
+ rather than DECL_SAVED_INSNS to decide whether or not this method
+ was declared inline.
+
+ * method.c (synthesize_method): Turn off DECL_INLINE if
+ function_cannot_inline_p thinks we're too large.
+
+ * typeck.c (build_indirect_ref): Use build_expr_type_conversion.
+
+Fri Mar 17 17:47:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (instantiate_type): Handle pmfs.
+
+ * typeck.c (convert_for_assignment): Check types when assigning one
+ pmf to another.
+
+ * decl.c (define_label): Fix logic for printing out the name of the
+ label in an error message.
+
+ * error.c (dump_expr): Support ARRAY_REF.
+
+Fri Mar 17 17:43:02 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Call build_t_desc here.
+ (finish_prevtable_vardecl): Instead of here.
+
+Fri Mar 17 14:40:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (expand_static_init): Also use expand_aggr_init if the
+ initializer is a TREE_LIST.
+ (grokdeclarator): Only pedwarn about extra qualification if -pedantic.
+
+ * pt.c (unify): Fix unification of return type.
+
+ * expr.c (fixup_result_decl): Use store_expr, rather than
+ emit_move_insn, to move the return value into the place where
+ callers will expect it.
+
+Thu Mar 16 22:05:25 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_offset_ref): Call assmble_external on functions.
+ * typeck.c (build_component_ref): Likewise.
+
+Thu Mar 16 20:28:16 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (struct saved_scope): Add members base_init_list and
+ member_init_list.
+ (push_to_top_level): Save current_base_init_list and
+ current_member_init_list to them.
+ (pop_from_top_level): Put it back.
+
+Thu Mar 16 19:21:14 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (instantiate_template): Call assemble_external.
+
+Thu Mar 16 18:07:54 1995 Brendan Kehoe <brendan@phydeaux.cygnus.com>
+
+ * class.c: Include rtl.h, to get NULL_RTX.
+ (finish_struct): Also zero out DECL_SAVED_INSNS, to avoid problems
+ on hosts with different sizes for each part of the union.
+ * tree.c: Also include rtl.h.
+ (layout_basetypes): Same change for DECL_SAVED_INSNS.
+
+Thu Mar 16 13:57:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (unify): Fix array domain unification for 64-bit targets.
+
+ * decl2.c (finish_file): Push bizarre type decl before walking the
+ vtables the first time.
+ (walk_vtables): OK, don't set prev to vars if the vardecl_fn messed
+ with TREE_CHAIN (prev).
+
+ * init.c (emit_base_init): Use convert_pointer_to_real instead of
+ convert_pointer_to when converting to a direct base.
+
+Wed Mar 15 20:26:29 1995 Mike Stump <mrs@cygnus.com>
+
+ * pt.c (type_unification): Handle transitive unification better.
+
+Wed Mar 15 13:56:16 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (walk_vtables): Always set prev to vars.
+ (mark_vtable_entries): Call assemble_external on the vtable entries.
+
+ * class.c (finish_struct): Set the vtable's size to NULL_TREE before
+ calling layout_decl, so that it gets updated properly.
+
+ Finally re-enable dynamic synthesis. This time it works.
+ * method.c (synthesize_method): Pass decl_function_context (fndecl)
+ to {push,pop}_cp_function_context.
+ * decl.c (push_cp_function_context): Now takes a tree argument.
+ (pop_cp_function_context): Likewise.
+ * call.c (build_method_call): Enable synthesis.
+ * lex.c (cons_up_default_function): Likewise.
+
+Tue Mar 14 19:14:19 1995 Doug Evans <dje@chestnut.cygnus.com>
+
+ * parse.y (setattrs): Chain onto prefix_attributes rather than
+ setting it.
+
+Wed Mar 15 13:00:00 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (pushdecl): Check if the type of the VAR_DECL is an
+ error_mark_node before trying to read TYPE_LANG_SPECIFIC.
+
+Mon Mar 13 21:00:28 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator, case ARRAY_REF): Wrap the exp with fold,
+ and convert the size and integer_one_node to the index type.
+
+Mon Mar 13 08:01:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Save the instance
+ argument, and tack it onto the front of the COND_EXPR to make the
+ semantics come out right. Grab the instance argument from
+ '*instance_ptrptr', rather than having it passed in separately.
+
+ * various: Change various consed-up comparison operations to have
+ boolean type. Remove the instance argument in calls to
+ get_member_function_from_ptrfunc.
+
+ * error.c (dump_expr): Dump true and false as "true" and "false".
+
+ * decl2.c (finish_file): Also set DECL_STATIC_FUNCTION_P on the
+ global init function.
+
+ * decl.c (finish_function): Only set DECL_EXTERNAL here if the
+ inline function is public.
+
+Sat Mar 11 00:58:03 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (is_friend): Be more careful about checking
+ DECL_CLASS_CONTEXT on non-member functions.
+
+ * decl2.c (finish_vtable_vardecl): Don't bother calling
+ assemble_external here.
+ (prune_vtable_vardecl): New function that just splices out the
+ vtable decl from the top-level decls.
+ (import_export_inline): Unset DECL_EXTERNAL at first.
+ (finish_file): Don't bother calling assemble_external here. Do
+ splice out all of the vtables.
+
+Fri Mar 10 14:42:29 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (finish_function): If we're not emitting the function yet,
+ call assemble_external for it.
+
+ * decl2.c (finish_prevtable_vardecl): Don't call mark_vtable_entries
+ here.
+ (finish_vtable_vardecl): Don't do the linkage deduction thing here.
+ Also don't splice out the current vtable if it is unused.
+ (finish_file): Move the second walk_vtables and the synthesis check
+ inside the 'reconsider' loop. Move thunk emission after the
+ 'reconsider' loop.
+
+Thu Mar 9 16:28:16 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * pt.c (tsubst): Don't bother calling cp_build_type_variant, since it
+ was passing bogus values for readonly and volatile from the original
+ template decl, not the resultant type of the tsubst call.
+
+ * class.c (duplicate_tag_error): Use cp_error_at to point out the
+ previous definition of the tag.
+
+Thu Mar 9 10:46:17 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (start_function): Clear base_init_insns and protect_list.
+ (struct cp_function): Add base_init_insns field.
+ (push_cp_function_context): Also save base_init_insns.
+ (pop_cp_function_context): Also restore base_init_insns.
+
+Wed Mar 8 13:31:44 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (member_init_ok_or_else): Check for initializing a static
+ member here.
+ (emit_base_init): Instead of here.
+
+Tue Mar 7 16:03:26 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Disable synthesis as needed.
+ * lex.c (cons_up_default_function): Likewise.
+
+Tue Mar 7 10:14:29 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y: New rules to allow attributes in a prefix position.
+ (prefix_attributes): New variable. Pass it into cplus_decl_attributes.
+ (setattr): New rule.
+ (reserved_declspecs, declmods): Catch attributes here.
+ * decl2.c (cplus_decl_attributes): Add PREFIX_ATTRIBUTES argument.
+ * decl.c (duplicate_decls): Pass DECL_MACHINE_ATTRIBUTES to
+ descendent typedef.
+ (grokdeclarator): Added code to support machine attributes.
+ * Makefile.in (stamp-parse): Expect 5 shift/reduce failures.
+
+Mon Mar 6 15:07:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Don't synthesize methods outside of a
+ function.
+
+ Make base initialization more re-entrant so that synthesis on the
+ fly will work (and, eventually, template instantation on the fly).
+ * init.c (sort_member_init): Don't bother with members that can't be
+ initialized. Reorganize a bit. Don't initialize base members here.
+ (sort_base_init): New function, like sort_member_init, but for base
+ classes. Steals some code from emit_base_init.
+ (emit_base_init): Simplify. Call sort_{member,base}_init before
+ doing any initialization, so we don't have to save
+ current_{member,base}_init_list in push_cp_function_context.
+ (expand_aggr_vbase_init_1): Adjust for sort_base_init.
+ (expand_aggr_vbase_init): Simplify.
+ * decl.c (struct cp_function): Add protect_list field.
+ (push_cp_function_context): Also save protect_list.
+ (pop_cp_function_context): Also restore protect_list.
+ * call.c (build_method_call): Enable synthesis at point of call.
+ * lex.c (cons_up_default_function): Likewise.
+
+ * parse.y: Turn -ansi checks back into -pedantic checks.
+
+ * init.c (build_new): Fix -fcheck-new for array new.
+
+Sat Mar 4 15:55:42 1995 Fergus Henderson <fjh@cs.mu.oz.au>
+
+ * typeck.c (build_compound_expr): warn if left-hand operand of
+ comma expression has no side-effects.
+
+Fri Mar 3 15:16:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y (primary): Change 'object qualified_id *' rules to 'object
+ overqualified_id *'.
+
+Fri Mar 3 12:48:17 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (unary_expr): Catch doing sizeof an overloaded function.
+ Make the error look the same as the one we issue in c_sizeof.
+
+ * typeck.c (build_binary_op_nodefault): Give an error for trying
+ to compare a pointer-to-member to `void *'.
+
+Fri Mar 3 11:28:50 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_unary_op): Handle bool increment with smoke and
+ mirrors here, rather than in expand_increment where it belongs,
+ because Kenner doesn't agree with me.
+
+Fri Mar 3 00:08:10 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokparms): Catch a PARM_DECL being used for a default
+ argument as well.
+
+Thu Mar 2 20:05:54 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (build_new): Don't allow new on a function type.
+
+ * parse.y (primary): Avoid a crash when seeing if the arg is of
+ the same type as that given for the typespec in an explicit dtor call.
+
+Thu Mar 2 00:49:38 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (finish_function): Change test for calling
+ mark_inline_for_output.
+
+Wed Mar 1 11:23:46 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_modify_expr): Complain if
+ build_default_binary_type_conversion fails.
+
+ * init.c (expand_default_init): Handle arguments of unknown type
+ properly.
+
+ * cvt.c (build_expr_type_conversion): Only complain about ambiguity
+ if 'complain'.
+ * various: Pass 'complain'.
+
+ * typeck.c (comptypes): Be more picky about comparing UPTs.
+
+Wed Mar 1 11:03:41 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): If declarator is null, say that the
+ type used has an incomplete type.
+
+Wed Mar 1 10:06:20 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (instantiate_template): Copy the template arguments to the
+ permanent_obstack. Also use simple_cst_equal to compare them when
+ looking for a previous instantiation.
+
+ * tree.c (make_deep_copy): Support copying INTEGER_TYPEs (assuming
+ they are array domain types).
+
+Tue Feb 28 23:24:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cp-tree.h: Define WANT_* constants for passing to
+ build_expr_type_conversion.
+ * cvt.c (build_expr_type_conversion): New function to build
+ conversion to one of a group of suitable types.
+ (build_default_binary_type_conversion): Use it.
+ * decl2.c (grok_array_decl): Likewise.
+ * typeck.c (build_unary_op): Likewise.
+ (build_array_ref): Tidy up a bit.
+ (build_binary_op): Likewise.
+
+Tue Feb 28 19:57:31 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't allow decl of an argument as `void'.
+
+Tue Feb 28 17:23:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y (typed_declspecs1): Add 'typespec reserved_typespecquals
+ reserved_declspecs' rule.
+
+ * parse.y (expr_or_declarator): Remove notype_qualified_id rule.
+ (direct_notype_declarator): Likewise.
+ (complex_direct_notype_declarator): Add notype_qualified_id rule.
+
+ * lex.c (real_yylex): Handle :> digraph properly.
+
+Tue Feb 28 12:26:29 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Check if it's a friend, not if it's
+ non-virtual, that's being initialized. Move the check up to
+ before FRIENDP would get cleared. Catch an unnamed var/field
+ being declared void. Say just `field' instead of `structure field'
+ in the error message. Only go for the operator name if DECLARATOR
+ is non-null.
+
+Tue Feb 28 00:08:01 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (start_function): Complain about abstract return type.
+ (grokdeclarator): Complain about declaring constructors and
+ destructors to be const or volatile. Complain about declaring
+ destructors to be static.
+
+ * pt.c (uses_template_parms): Handle pmfs.
+
+ * decl.c (grokdeclarator): Don't call variable_size for array bounds
+ that only depend on template constant parameters.
+
+Mon Feb 27 15:38:16 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * error.c (dump_decl): Only look to see if it's a vtable if we
+ actually have a name to check out.
+
+Mon Feb 27 13:37:53 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (convert_to_aggr): Lose misleading shortcut.
+
+Sun Feb 26 17:27:32 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * decl.c (set_nested_typename): Always set DECL_IGNORED_P,
+ not just for dwarf.
+
+Sun Feb 26 00:10:18 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't allow a static member to be
+ declared `register'.
+
+ * init.c (make_friend_class): Move up to a pedwarn for the warning
+ about a class declaring friends with itself.
+
+ * decl.c (grokdeclarator): You can't do `volatile friend class foo'
+ or `inline friend class foo'. Only try to make a friend out of
+ TYPE if we didn't already reset it to integer_type_node.
+
+Sat Feb 25 22:32:03 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't allow initialization of a
+ non-virtual function.
+
+ * decl.c (start_function): Do a pedwarn if we're changing `main'
+ to have an int return type.
+
+Sat Feb 25 00:02:05 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_modify_expr): Handle simple assignment from
+ TARGET_EXPRs by building up an RTL_EXPR to force expansion. Whew.
+
+Fri Feb 24 18:27:14 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Also don't allow virtual outside of a
+ class decl for a scope method definition performed at global binding.
+
+ * init.c (build_offset_ref): Don't allow creation of an OFFSET_REF
+ of a bitfield.
+
+ * decl.c (grokdeclarator): Don't allow a const to be declared mutable.
+
+ * typeck.c (build_binary_op): Return an error_mark_node if either
+ one of the args turned into an error_mark_node when we tried to
+ use default_conversion.
+
+ * typeck.c (build_unary_op): Forbid using postfix -- on a bool.
+
+ * decl.c (grokdeclarator): Allow `signed' and `unsigned' to be
+ used on `__wchar_t'.
+
+Fri Feb 24 13:59:53 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (end_protect_partials): Do it the right way.
+
+Wed Feb 22 15:42:56 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Upgrade warning about
+ comparing distinct pointer types to pedwarn.
+
+ * typeck2.c (digest_init): Cope with extra braces.
+
+ * typeck.c (build_binary_op_nodefault): Use tree_int_cst_sgn instead
+ of INT_CST_LT (..., interger_zero_node).
+
+Wed Feb 22 14:45:52 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * except.c [!TRY_NEW_EH] (end_protect_partials): Define dummy
+ function for systems that don't have EH.
+
+Tue Feb 21 19:18:31 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (can_convert_arg): Like can_convert, but takes an arg as
+ well.
+
+ * pt.c (type_unification): Allow implicit conversions for parameters
+ that do not depend on template parameters.
+
+Tue Feb 21 18:43:48 1995 Douglas Rupp <drupp@cs.washington.edu>
+
+ * Make-lang.in, config-lang.in: ($exeext): New macro.
+ * Make-lang.in: Try a "cp" if "ln" fails.
+ * cp-tree.h (decl_attributes): Added argument.
+ * decl2.c (cplus_decl_attribute): Add arg to decl_attributes.
+ * cp/g++.c: Added #ifdefs for sys/file.h and process.h for NT.
+ Modified spawnvp to have to correct number of arguments for OS/2, NT.
+
+Tue Feb 21 18:36:55 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (finish_function): Add calls to end_protect_partials to end
+ the exception region that protects constructors so that partially
+ constructed objects can be partially destructed when the constructor
+ throws an exception.
+ * init.c (perform_member_init, sort_member_init, emit_base_init):
+ Added support for partially constructed objects.
+ * init.c (build_partial_cleanup_for): New routine to do partial
+ cleanups of a base class.
+ * decl2.c (finish_file): Move the emitting of the exception table
+ down, after we emit all code that might have exception regions in
+ them.
+ * except.c (end_protect_partials, might_have_exceptions_p): New
+ routines.
+ (emit_exception_table): Always output table if called.
+ * cp-tree.h (protect_list, end_protect_partials,
+ might_have_exceptions_p, emit_exception_table): Added.
+
+Tue Feb 21 16:05:59 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * gc.c (build_typeid): Pass a NULL_TREE, not the bogus, unused
+ address of a local variable.
+ * class.c (build_vfn_ref): Only try to build the PLUS_EXPR if we
+ were given a non-null PTR_TO_INSTPTR.
+
+Tue Feb 21 01:53:18 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (duplicate_decls): Always lay out the merged decl.
+
+ * decl2.c (finish_vtable_vardecl): Don't do vtable hack on templates.
+ (finish_prevtable_vardecl): Likewise.
+
+ * method.c (synthesize_method): Set interface_{unknown,only}
+ according to the settings for our class, not the file where it comes
+ from.
+
+Sat Feb 18 12:26:48 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Handle systems that define __i386__ but not __i386.
+
+Fri Feb 17 15:31:31 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (reparse_decl_as_expr): Support being called without a
+ type argument.
+
+ * parse.y (primary): Add '(' expr_or_declarator ')'. Adds 4 r/r
+ conflicts. Sigh.
+
+Fri Feb 17 12:02:06 1995 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (template_def, fndef, fn.def1, return_init, condition,
+ initdcl0, initdcl, notype_initdcl0, nomods_initdcl0,
+ component_decl_1, after_type_component_declarator0,
+ notype_component_declarator0, after_type_component_declarator,
+ notype_component_declarator, after_type_component_declarator,
+ full_parm, maybe_raises, exception_specification_opt): Fix up,
+ include exception_specification_opt maybeasm maybe_attribute and
+ maybe_init if missing. Rename maybe_raises to
+ exception_specification_opt to match draft wording. Use maybe_init
+ to simplify rules.
+
+Fri Feb 17 01:54:46 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_new): Set TREE_NO_UNUSED_WARNING on COMPOUND_EXPRs
+ built for news of scalar types.
+
+Thu Feb 16 17:48:28 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Update code for warning
+ about signed/unsigned comparisons from C frontend. Realize that the
+ code in the C frontend is, if anything, even more bogus. Fix it.
+ (build_binary_op): Undo default_conversion if it wasn't useful.
+
+ * typeck.c (build_unary_op, ADDR_EXPR): Lose bogus special case for
+ PRE*CREMENT_EXPR.
+
+ * decl2.c (import_export_vtable): Don't try the vtable hack
+ if the class doesn't have any real non-inline virtual functions.
+ (finish_vtable_vardecl): Don't bother trying to find a non-inline
+ virtual function in a non-polymorphic class.
+ (finish_prevtable_vardecl): Likewise.
+
+ * decl2.c (import_export_vtable): Use and set DECL_INTERFACE_KNOWN.
+
+ * cp-tree.h (DECL_INTERFACE_KNOWN): Use DECL_LANG_FLAG_5.
+
+ * init.c (expand_virtual_init): Always call assemble_external.
+
+ * class.c (build_vfn_ref): Always call assemble_external.
+ (build_vtable): Always call import_export_vtable.
+ (prepare_fresh_vtable): Likewise.
+ (add_virtual_function): Don't bother setting TREE_ADDRESSABLE.
+
+Thu Feb 16 03:28:49 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (finish_struct): Use TYPE_{MIN,MAX}_VALUE to determine
+ whether an enumerated type fits in a bitfield.
+
+Wed Feb 15 15:38:12 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (grow_method): Update method_vec after growing the class
+ obstack.
+
+Wed Feb 15 13:42:59 1995 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (handler_seq): Push a level for the catch parameters.
+
+Wed Feb 15 12:42:57 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (emit_base_init): Update BINFO_INHERITANCE_CHAIN on my
+ bases, in case they've been clobbered.
+
+Wed Feb 15 12:07:29 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (finish_base_struct): Set up BINFO_INHERITANCE_CHAIN here,
+ so that one day it will always be valid.
+ * tree.c (propagate_binfo_offsets, layout_vbasetypes): Likewise.
+
+ * cp-tree.h (copy_binfo): Removed, unused.
+ * tree.c (copy_binfo): Likewise.
+
+Wed Feb 15 00:05:30 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_new): Save the allocation before calling
+ expand_vec_init on it.
+
+ * decl.c (finish_enum): The TYPE_PRECISION of the enum type mush
+ match the TYPE_PRECISION of the underlying type for constant folding
+ to work.
+
+Tue Feb 14 15:31:25 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (push_eh_entry, expand_start_all_catch,
+ expand_leftover_cleanups, expand_end_catch_block): Keep track of
+ the context in which the exception region occurs.
+ (build_exception_table): If the region was not output, don't output
+ the entry in the eh table for it.
+
+Tue Feb 14 02:15:43 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (expand_default_init): Only use a previous constructor call
+ if it's a call to our constructor. Does the word "Duh" mean
+ anything to you?
+
+ * decl.c (grokparms): Fine, just don't call
+ convert_for_initialization at all. OK? Happy now?
+
+Mon Feb 13 02:23:44 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cp-tree.h (CLASSTYPE_FIRST_CONVERSION): Make sure that the class
+ method vector has a second element before returning it.
+
+ * decl.c (grokparms): Don't strip REFERENCE_TYPE before calling
+ convert_for_initialization.
+
+Sun Feb 12 03:57:06 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_modify_expr): Compare function name to
+ constructor_name (current_class_type) instead of current_class_name.
+
+ * decl.c (grokparms): Don't do anything with the return value of
+ convert_for_initialization.
+
+ * error.c (dump_decl): Also dump_readonly_or_volatile on the decl.
+
+ * decl.c (duplicate_decls): Tweak error message.
+
+ * typeck.c (build_const_cast): Implement checking.
+ (build_reinterpret_cast): Implement some checking.
+
+ * cp-tree.h (CONV_FORCE_TEMP): Require a new temporary when
+ converting to the same aggregate type.
+ (CONV_STATIC_CAST): Include it.
+ (CONV_C_CAST): Likewise.
+ * cvt.c (convert_force): Use CONV_C_CAST instead of CONV_OLD_CONVERT.
+ (cp_convert): Only force a new temporary if CONV_FORCE_TEMP.
+
+Fri Feb 10 16:18:52 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_c_cast): Use non_lvalue to tack something on
+ where necessary.
+
+ * decl.c (auto_function): Now a function.
+ * except.c (init_exception_processing): terminate, unexpected,
+ set_terminate, and set_unexpected have C++ linkage.
+
+ * typeck.c (build_unary_op, TRUTH_NOT_EXPR): Use convert instead of
+ truthvalue_conversion for converting to bool, as it handles
+ user-defined conversions properly.
+ (condition_conversion): Likewise.
+
+ * except.c (expand_throw): Don't call convert_to_reference.
+ Pass the correct parameters to build_new.
+
+ * method.c (do_build_assign_ref): Don't use access control when
+ converting to a base reference here.
+ (do_build_copy_constructor): Or here.
+
+ * init.c (build_new): Unset TREE_READONLY on the dereferenced
+ pointer before assigning to it.
+
+ * decl.c (maybe_build_cleanup): Don't bother stripping const here.
+
+ * decl2.c (delete_sanity): You can now delete pointer to const.
+
+Fri Feb 10 13:28:38 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * decl.c (finish_function): Don't rely on actual parameters being
+ evaluated left-to-right.
+ * except.c (expand_end_catch_block): Likewise.
+
+Fri Feb 10 00:52:04 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * tree.c (real_lvalue_p): Like lvalue_p, but class temps aren't
+ considered lvalues.
+ * cvt.c (convert_to_reference): Use real_lvalue_p instead of
+ lvalue_p.
+
+ * cvt.c (build_type_conversion_1): Don't call convert on aggregate
+ types.
+ (convert_to_reference): Fix erroneous text substitution.
+
+ * typeck2.c (initializer_constant_valid_p): Update from C frontend.
+ Add new argument to all callers.
+
+ * typeck.c (convert_arguments): Check for error_mark_node before
+ trying to do anything with the actual parameter.
+
+ * typeck.c (condition_conversion): Build up a CLEANUP_POINT_EXPR and
+ fold it.
+ (bool_truthvalue_conversion): Remove. Fix all callers to call
+ truthvalue_conversion instead.
+ (various): Fold CLEANUP_POINT_EXPRs.
+
+ * parse.y (conditions): Call condition_conversion rather than
+ building up a CLEANUP_POINT_EXPR.
+
+ * pt.c (end_template_decl): Don't warn_if_unknown_interface here
+ under -falt-external-templates.
+
+Thu Feb 9 05:24:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_new): Complain about new of const type without
+ initializer. Other cleanup.
+
+ * call.c (compute_conversion_costs): Don't call
+ build_type_conversion with a reference type; convert to the target
+ type and check its lvaluetude.
+ * cvt.c (convert_to_reference): Likewise.
+
+ * cvt.c (build_type_conversion_1): There will never be any need to
+ dereference references here now.
+
+Thu Feb 9 00:37:47 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_builtin_throw): Make sure we only `use' the
+ value of return_val_rtx.
+
+Wed Feb 8 15:45:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y (structsp): Don't complain about declaring a type being
+ defined to be a friend.
+
+ * decl2.c (warn_if_unknown_interface): Note the template in question
+ and the point of instantiation, for -falt-external-templates.
+ * lex.c (reinit_parse_for_method): Pass the decl to
+ warn_if_unknown_interface.
+ * pt.c (instantiate_template): Likewise.
+ (end_template_decl): Likewise.
+
+ * decl.c (set_nested_typename): Set IDENTIFIER_TYPE_VALUE on the
+ nested name again, to make local classes work a bit better.
+
+ * typeck.c (build_function_call_real): Dereference reference after
+ checking for incomplete type.
+
+ * init.c (build_new): Accept new of const and volatile types.
+
+Wed Feb 8 14:04:16 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Fix error message.
+
+Wed Feb 8 03:16:15 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (convert_for_initialization): Do bash arrays when
+ converting to a reference to non-array.
+
+Tue Feb 7 15:50:33 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (cp_convert): Don't call convert_to_reference, or
+ automatically dereference references. Do pass reference conversions
+ to cp_convert_to_pointer.
+ (cp_convert_to_pointer): Support references.
+
+ * call.c (build_method_call): Don't build up a reference to the
+ parameter here; let build_overload_call handle that.
+
+ * typeck.c (build_c_cast): Call convert_to_reference directly if
+ converting to a reference type.
+ * method.c (do_build_copy_constructor): Likewise.
+ * method.c (do_build_copy_constructor): Likewise.
+ (do_build_assign_ref): Likewise.
+
+ * call.c (build_method_call): Dereference a returned reference.
+ * typeck.c (build_function_call_real): Likewise.
+
+ * decl.c (xref_basetypes): Check for unions with basetypes here.
+ (xref_tag): Instead of here.
+
+ * pt.c (process_template_parm): Template type parm decls are
+ artificial.
+
+Mon Feb 6 04:32:09 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y (typed_declspecs): Add missing semicolon.
+ (do_xref_defn): Resurrect.
+ (named_class_head_sans_basetype): Move template specialization
+ definition cases to named_class_head_sans_basetype_defn.
+
+ * decl2.c (grokfield): Call pushdecl_class_level after setting the
+ TYPE_NAME, not before.
+
+Sun Feb 5 02:50:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (convert_harshness): Don't call sorry here. Don't allow
+ conversions between function pointer types if pedantic.
+
+ * pt.c (overload_template_name): Pass globalize=1 to xref_tag.
+
+ * lex.c (cons_up_default_function): Use the full name for the return
+ type of op=.
+
+ * decl.c (set_nested_typename): Don't worry about anonymous types,
+ as they already have a unique name.
+ (pushdecl): Remove redundant set_nested_typename
+ (xref_tag): Split out base handling into xref_basetypes.
+
+ * cp-tree.h (TYPE_INCOMPLETE): New macro; TEMPLATE_TYPE_PARMs are
+ not considered incomplete even though their definition is unknown.
+
+ * decl.c (xref_defn_tag): Lose.
+ (xref_tag): xref_next_defn = ! globalize.
+ (pushdecl): Don't set DECL_NESTED_TYPENAME on artificial decls. The
+ ones that should have it set will have it set by pushtag.
+ (pushdecl_class_level): Likewise.
+ (pushtag): Tidy up a bit.
+ (set_nested_typename): Push a decl for the nested typename from
+ here, rather than from xref_defn_tag.
+
+ * parse.y (do_xref): Lose.
+ (named_class_head): If we see 'class foo:' we know it's a
+ definition, so don't worry about base lists for non-definitions.
+
+ * pt.c (push_template_decls): Template parm decls are artificial.
+
+ * decl.c (duplicate_decls): Restore check for qualifier
+ disagreement for non-functions.
+ (decls_match): Remove check for qualifier disagreement.
+
+Fri Feb 3 14:58:58 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grok_reference_init): Convert initializer from
+ reference.
+ * typeck.c (convert_for_initialization): Likewise.
+
+ * decl.c (duplicate_decls): Propagate DECL_NESTED_TYPENAME.
+
+ * cvt.c (cp_convert): Don't convert to the same class type by just
+ tacking on a NOP_EXPR.
+ (convert_to_reference): Use comp_target_types instead of comptypes
+ so that we don't allow conversions two levels down.
+
+Thu Feb 2 15:07:58 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (build_vbase_path): Bash types to make the backend happy.
+ * cvt.c (build_up_reference): Bash the types bashed by
+ build_vbase_path to be reference types instead of pointer types.
+ (convert_to_reference): Likewise.
+
+ * typeck.c (build_c_cast): Don't strip NOPs if we're converting to a
+ reference type.
+
+ * parse.y (structsp): Put back error for 'struct B: public A;'.
+
+Wed Feb 1 23:02:06 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Add support for mips systems that don't define __mips
+ but do define mips, like Ultrix.
+
+Wed Feb 1 22:39:07 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Add support for exception handling on the Alpha.
+
+Wed Feb 1 10:12:14 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_file): Fix bug in Jan 31st change.
+
+Tue Jan 31 16:59:15 1995 Gerald Baumgartner <gb@lorenzo.cs.purdue.edu>
+
+ * sig.c (build_signature_pointer_or_reference_type): Don't set
+ IS_AGGR_TYPE for signature pointers/reference so expand_default_init
+ doesn't expect to find a copy constructor.
+ * call.c (build_method_call): Treat signature pointers/reference
+ as if IS_AGGR_TYPE were set.
+
+Tue Jan 31 13:28:56 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (get_typeid): Pawn off error messages to build_t_desc.
+ (build_t_desc): Inform the user here if they try and build
+ with -frtti and don't include <typeinfo.h>.
+
+ * decl2.c (finish_prevtable_vardecl): Support rescanning.
+ (finish_file): Move finish_prevtable_vardecl up to before the global
+ initializers are done as tdecls are initialized in the global
+ initializer. Also Pick up any new tdecls or vtables needed by
+ synthesized methods.
+
+ * class.c (finish_struct): Simplify. We have to do rtti scanning at
+ end, so we might as well do all of it there.
+
+Tue Jan 31 05:35:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Fix -fthis-is-variable for 32-bit
+ targets, too.
+
+Tue Jan 31 00:11:04 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_prevtable_vardecl): New routine, mostly split from
+ finish_vtable_vardecl. It has the first half functionality from
+ that routine.
+ * decl2.c (finish_vtable_vardecl): Update to not include stuff not
+ in finish_prevtable_vardecl.
+ * decl2.c (finish_file): Call finish_prevtable_vardecl.
+ * gc.c (build_generic_desc): Allow it to be called when not at the
+ global binding layer, but behave as if we were.
+ (build_t_desc): Rearrange a bit so that it really works and is
+ easier to follow.
+ * class.c (finish_struct): Don't decide on tdecls here, as we have
+ to wait until the end of the file in general to decide whether or
+ not they come out.
+
+Mon Jan 30 01:00:40 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_delete): Check access to operator delete before
+ calling the destructor.
+ * method.c (build_opfncall, DELETE_EXPR): build_method is allowed to
+ return error_mark_node.
+ * call.c (build_method_call): Use the one-argument op delete even if
+ it's an error.
+
+ * init.c (build_new): Fix -fthis-is-variable support.
+ * call.c (build_method_call): Likewise.
+
+ * call.c (convert_harshness): Make conversion from a pointer to bool
+ worse than conversion to another pointer.
+
+Sat Jan 28 16:46:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_new): Check new return value if -fcheck-new.
+
+ * lex.c (check_newline): Clear end_of_file when we're done, too.
+
+Sat Jan 28 10:38:39 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Make rtti TD tables follow
+ vtables whereever they go.
+
+ * gc.c (build_t_desc): Remove old way of setting it up, as it wasn't
+ right.
+
+Sat Jan 28 09:10:44 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Now set the
+ interface/implementation of vtables on the first virtual function,
+ if one exists, otherwise we use the old method. This is a major win
+ in terms of cutting down the size of objects and executables in
+ terms of text space and data space. Now most of the savings that
+ #pragma interface/implementation gives is automatic in a fair number
+ of cases.
+
+Sat Jan 28 04:57:33 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grokdeclarator): Discard the template parameters in a
+ template constructor declaration so that the function is always
+ named constructor_name (ctype).
+
+ * lex.c (check_newline): Use ungetc to put back the character before
+ calling HANDLE_PRAGMA.
+
+Fri Jan 27 17:23:47 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (check_classfn): If the cname is T<int> and fn_name is T,
+ make sure we still match them.
+
+Fri Jan 27 16:32:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y: Add END_OF_LINE token.
+
+ * lex.c (check_newline): Set linemode when we see a # directive, and
+ unset it when we're done. Turn all 'return's into 'goto skipline'.
+ Fix all uses of '\n', since we won't see it anymore. Put back the
+ character we read before checking for a sysv or target pragma.
+ (real_yylex): If we see an EOF in linemode, return END_OF_LINE.
+ (handle_sysv_pragma): Don't look at the input stream; quit when we
+ see an END_OF_LINE token.
+
+ * input.c (getch): Return EOF if we're in line mode and at the end
+ of a line.
+ (put_back): Don't put back an EOF.
+
+Thu Jan 26 19:26:34 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Do the newing of the exception object
+ before we load the type descriptor or the address so that we don't
+ wipe any of the values out.
+
+Thu Jan 26 19:20:00 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (init_exception_processing): Don't use r12 on the rs6000.
+
+Tue Jan 24 16:36:31 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grokparms): Don't try to build up a reference at this point.
+
+ * typeck2.c (build_functional_cast): Don't assume that a NOP_EXPR
+ will suffice to convert from integer_zero_node.
+
+Wed Jan 25 15:02:09 1995 David S. Miller <davem@nadzieja.rutgers.edu>
+
+ * class.c (instantiate_type): Change error message text.
+ * typeck2.c (store_init_value): Likewise.
+
+Mon Jan 23 21:57:14 1995 Mike Stump <mrs@cygnus.com>
+
+ * pt.c (tsubst): When we copy a node, don't forget to copy
+ TREE_CHAIN, we use it later.
+
+Mon Jan 23 03:33:47 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (convert_for_assignment): Initialize variable before use.
+
+Fri Jan 20 01:17:59 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * g++.c (main): Link with both libstdc++ and libg++ if called as
+ something ending with "g++", otherwise only libstdc++. Move -lm to
+ the end of the line.
+
+Thu Jan 19 15:43:11 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Don't mess with 'this' before calling
+ compute_conversion_costs.
+
+Wed Jan 18 15:40:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * search.c (get_matching_virtual): Give line number for previous
+ declaration.
+
+ * call.c (convert_harshness): Handle conversions to references
+ better.
+
+ * cvt.c (build_up_reference): OK, handle {MIN,MAX}_EXPR *properly*.
+
+Wed Jan 18 15:21:38 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (instantiate_type): Use DECL_CHAIN to walk lists instead,
+ as the TREE_CHAIN for methods will take us to the next differently
+ named function, DECL_CHAIN won't.
+
+Wed Jan 18 14:26:59 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * tree.c (lvalue_p): Handle {MIN,MAX}_EXPR.
+
+ * decl2.c (lang_decode_option): -Wall implies -Wparentheses.
+ warn_parentheses defaults to 0.
+
+ * decl.c (grokparms): Put back call to require_instantiated_type.
+
+Tue Jan 17 19:56:15 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (exception_section): Use the data section on the rs6000.
+ Change calling convention for named_section.
+
+Wed Jan 17 18:20:57 1994 Fergus Henderson <fjh@munta.cs.mu.oz.au>
+
+ * cp-tree.h : Make if (x=0) warn with wall
+ * parse.y : Make if (x=0) warn with wall
+
+Tue Jan 17 14:12:00 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (BOOL_TYPE_SIZE): BITS_PER_WORD if SLOW_BYTE_ACCESS,
+ BITS_PER_UNIT otherwise.
+
+ * search.c (get_matching_virtual): Don't check the binfo if the
+ types are the same.
+
+ * cvt.c (cp_convert): Just call truthvalue_conversion to convert to
+ bool.
+
+Mon Jan 16 13:28:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * various: Use boolean_type_node, boolean_true_node,
+ boolean_false_node.
+
+ * search.c (get_matching_virtual): Allow covariant returns that
+ don't require pointer adjustment.
+
+ * typeck.c (build_conditional_expr): Don't call default_conversion
+ on ifexp.
+
+ * cvt.c (build_up_reference): Handle MIN_EXPR and MAX_EXPR.
+
+ * decl.c (grokdeclarator): Upgrade warning about &const to pedwarn.
+
+Sun Jan 15 22:17:32 1995 David Binderman <dcb@lovat.fmrco.COM>
+
+ * pt.c (do_function_instantiation): Free targs once we're done.
+
+Sun Jan 15 22:17:32 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (BOOL_TYPE_SIZE): Defaults to BITS_PER_WORD.
+ (init_decl_processing): Use BOOL_TYPE_SIZE instead of CHAR_TYPE_SIZE
+ for bool.
+
+Sat Jan 14 05:33:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (finish_file): We need to mess up if there are any
+ variables in the list, not just if there is one with a constructor.
+
+Fri Jan 13 14:42:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (duplicate_decls): Propagate DECL_STATIC_{CON,DE}STRUCTOR.
+ (finish_function): Handle DECL_STATIC_{CON,DE}STRUCTOR.
+ (finish_function): Trust rest_of_compilation.
+
+ * decl2.c (finish_file): Also call functions designated as static
+ constructors/destructors.
+
+ * decl.c (grokdeclarator): Allow access decls of operator functions.
+ (grokparms): Only do convert_for_initialization if the initializer
+ has a type.
+ (duplicate_decls): Put back push_obstacks_nochange call.
+
+ * lex.c (real_yylex): Downgrade complaint about the escape sequence
+ being too large from pedwarn to warning.
+
+ * decl.c (grokdeclarator): Don't complain about long long in system
+ headers.
+
+ * lex.c (real_yylex): Handle digraphs.
+
+Thu Jan 12 12:17:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (init_decl_processing): -f{no-,}strict-prototype only
+ affects C linkage declarations now.
+
+ * typeck.c (comp_target_types): Grok simple contravariant conversions.
+ (common_type): t1 and t2 are interchangeable.
+
+ * various: Test return value of comp_target_types differently in
+ different places; it now returns -1 for a contravariant conversion
+ (which is fine in symmetric cases).
+
+ (common_type): Prefer long double to double even when
+ they have the same precision.
+
+ * decl.c (grokparms): Call convert_for_initialization to check
+ default arguments.
+
+ * init.c (build_new): void_type_node has a size (of 0).
+
+ * decl.c (decls_match): Also check for agreement of TREE_READONLY
+ and TREE_THIS_VOLATILE.
+ (push_class_level_binding): Properly handle shadowing of
+ nested tags by fields.
+
+ * search.c (dfs_pushdecls): Likewise.
+
+ * decl2.c (finish_file): Don't second-guess self-initialization.
+
+ * cvt.c (convert_to_reference): Work with expr directly, rather than
+ a copy.
+
+ * decl.c (push_overloaded_decl): Only shadow artificial TYPE_DECLs.
+
+ * init.c (add_friend): Downgrade duplicate friend message from
+ pedwarn to warning.
+
+ * decl.c (duplicate_decls): Push obstacks before calling common_type.
+
+Thu Jan 12 17:15:21 1995 Michael Ben-Gershon <mybg@cs.huji.ac.il>
+
+ * except.c (push_eh_entry): set LABEL_PRESERVE_P flag for
+ exception table labels.
+ (expand_start_all_catch): Likewise.
+ (expand_leftover_cleanups): Likewise.
+ (expand_end_catch_block): Likewise.
+ * except.c (make_first_label): new function.
+ (expand_start_all_catch): add a call to make_first_label() before
+ using a label as a jump destination.
+ (expand_end_all_catch): Likewise.
+ (expand_leftover_cleanups): Likewise.
+ (expand_end_catch_block): Likewise.
+ (expand_builtin_throw): Likewise.
+ (expand_throw): Likewise.
+ * except.c: Add ARM processor support for exception handling.
+
+Thu Jan 12 12:17:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ (complete_array_type): Copy code from C frontend.
+
+ * lex.c (real_yylex): Don't multiply the length of a wide string
+ literal by WCHAR_BYTES.
+
+ * decl.c (pushdecl): Check for redeclaration of wchar_t here.
+ (duplicate_decls): Instead of here.
+ (define_label): Complain about a label named wchar_t.
+ (grokdeclarator): Complain about declarations of
+ operator-function-ids as non-functions.
+
+ * typeck.c (unary_complex_lvalue): Also wrap prefix -- and ++ in
+ COMPOUND_EXPRs.
+ (build_unary_op): Wrap unary plus in a NON_LVALUE_EXPR.
+
+ * lex.c (real_yylex): Don't skip whitespace when reading the next
+ character after ->.
+
+Wed Jan 11 16:32:49 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Allow cc1plus to be built with native compiler on rs6000.
+ (expand_start_all_catch): Add assemble_external calls for various
+ routines we call.
+ (expand_leftover_cleanups): Likewise.
+ (expand_start_catch_block): Likewise.
+ (do_unwind): Likewise.
+ (expand_builtin_throw): Likewise.
+
+Wed Jan 11 01:05:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (pushtag): Only look for a previous decl in the current
+ binding level. Use explicit global scope in DECL_NESTED_TYPENAME.
+
+ * gxx.gperf: Add __signature__ and __sigof__ keywords.
+
+ * decl2.c (lang_decode_option): -ansi does not set flag_no_asm. It
+ does set flag_no_gnu_keywords and flag_operator_names.
+
+ * lex.c (init_lex): 'overload' is not a keyword unless -traditional.
+ Unset extension keywords if -fno-gnu-keywords.
+ Allow operator names ('bitand') if -foperator-names.
+ Never unset 'asm'; -fno-asm only affects 'typeof'.
+
+ * decl.c (lookup_name_real): The got_object special lookup only
+ applies to types.
+
+Tue Jan 10 18:07:51 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * spew.c (yylex): Also use DECL_NESTED_TYPENAME if got_object is set.
+
+ * parse.y (primary): Unset got_object after all rules that use the
+ 'object' nonterminal.
+ (object): Set got_object.
+
+ * lex.h: Declare got_object.
+
+ * decl.c (lookup_name_real): Also lookup names in the context of an
+ object specified.
+
+Tue Jan 10 14:30:30 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Use ptrdiff_type_node
+ for things that have to be added to pointers, not size_type. Cures
+ problems with pointer to members on Alphas.
+ (build_binary_op_nodefault): Likewise.
+ (get_delta_difference_: Likewise.
+ (build_ptrmemfunc): Likewise.
+
+Tue Jan 10 01:49:25 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (pushtag): Stick the new decl in TYPE_NAME before pushing
+ it.
+
+ * typeck.c (build_component_ref): Don't build up a COMPONENT_REF
+ when dealing with overloaded member functions; just act like
+ build_offset_ref.
+ (commonparms): Remove misleading comment.
+
+ * decl.c (duplicate_decls): Complain about repeated default
+ arguments here.
+ (redeclaration_error_message): Instead of here.
+ (pushdecl): Complain about missing default arguments here.
+ (grokparms): Instead of here.
+ (lookup_name_current_level): Also match on DECL_ASSEMBLER_NAME.
+ (grok_reference_init): Do not complain about missing initializer if
+ declared 'extern'.
+
+ * search.c (lookup_field): Don't return a TYPE_DECL if there is a
+ function alternative and want_type is not set.
+
+Mon Jan 9 18:16:23 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (pushtag): Don't set TYPE_NAME to an identifier. Do push
+ the decl when the type has no TYPE_NAME.
+ (lookup_nested_type): Don't assume that type has TYPE_NAME set.
+ (lookup_name_real): Call lookup_field with want_type =
+ prefer_type.
+
+ * search.c (lookup_field): Handle want_type properly in the presence
+ of fields with the same name.
+
+ * decl.c (set_nested_typename): Set nested name for file-scope types
+ to include leading ::.
+ (pushdecl): Set the nested typename if the decl doesn't have one,
+ rather than if the type's canonical decl doesn't have one.
+
+Mon Jan 9 03:44:33 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (convert_for_assignment): Complain about contravariance
+ violation here.
+ (comp_target_types): Instead of here.
+ (build_unary_op): resolve_offset_ref before checking for a valid
+ type.
+
+ * spew.c (yylex): Decrement looking_for_typename after we see a
+ _DEFN.
+
+ * decl.c (pushdecl): Don't install an artificial TYPE_DECL in
+ IDENTIFIER_LOCAL_VALUE if we already have a decl with that name.
+
+ * typeck.c (convert_for_assignment): Converting pointers to bool
+ does not need a cast.
+
+Sun Jan 8 18:16:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (instantiate_type): Initialize nsubsts parm.
+
+ * pt.c (do_function_instantiation): Likewise.
+
+Sat Jan 7 14:37:05 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (tsubst): Use TREE_STATIC instead of DECL_INLINE &&
+ DECL_SAVED_INSNS to determine whether or not we've seen a definition
+ of this function.
+ (instantiate_template): Likewise.
+
+ * call.c (convert_harshness): Allow const reference binding when
+ called from the overloading code, but not when called from
+ can_convert (since it isn't a conversion).
+ (convert_harshness): Put back some disabled code.
+
+Fri Jan 6 14:10:57 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (convert_harshness): There is no implicit conversion from
+ void* to other pointer types (unless the parameter is (void*)0).
+ (convert_harshness): Non-lvalues do not convert to reference types.
+
+ * class.c (finish_struct_methods): Still set
+ TYPE_HAS_{INT,REAL}_CONVERSION.
+
+ * call.c (can_convert): Don't use aggregate initialization.
+
+ * cp-tree.h: Declare lookup_conversions.
+
+Thu Jan 5 21:08:00 1995 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (simple_stmt): Fix duplicate case value error messages to
+ be more readable.
+
+Wed Jan 4 16:44:19 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (build_type_conversion): Total rewrite to use
+ convert_harshness instead of reproducing conversion logic here. Now
+ much shorter.
+
+ * call.c (convert_harshness): Support conversions to bool.
+ (can_convert): Checks whether a conversion is less harsh
+ than USER_CODE, for build_type_conversion.
+
+ * search.c (add_conversions): Function for passing to dfs_walk which
+ adds all the type conversion operators in the current type to a list.
+ (lookup_conversions): Calls dfs_walk with add_conversions and return
+ the list.
+ (dfs_walk): Don't require a qfn.
+
+ * cp-tree.h: Lose CLASSTYPE_CONVERSIONS hackery.
+ (CLASSTYPE_FIRST_CONVERSION): Points to elt 1 of CLASSTYPE_METHOD_VEC.
+
+ * class.c (finish_struct_bits): Lose CLASSTYPE_CONVERSIONS hackery.
+ (grow_method): A separate function for building onto the growing
+ method vector.
+ (finish_struct_methods): Use it. Put all type conversion operators
+ right after the constructors. Perhaps we should sort the methods
+ alphabetically?
+
+Mon Jan 2 14:42:58 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Lose another misleading shortcut.
+
+Fri Dec 30 17:57:30 1994 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_bltn_desc): Handle bool as a built-in type.
+
+Fri Dec 30 14:20:21 1994 Mike Stump <mrs@cygnus.com>
+
+ * tree.c (layout_vbasetypes): Ensure that we don't loose alignment
+ on the complete type because of small virtual bases.
+
+Fri Dec 30 12:22:29 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (n_incomplete): Bump n_incomplete up to int to match C
+ front end.
+ (pushdecl): Also count decls pushed that are of a type being defined
+ as incomplete things.
+ * class.c (finish_struct): Move hack_incomplete_structures up to
+ just after we set it as not being defined, so that the decls we
+ build for RTTI don't count as incomplete.
+
+Thu Dec 29 18:20:57 1994 Mike Stump <mrs@cygnus.com>
+
+ * pt.c (tsubst): Fix problem with defining constructors in templated
+ classes with virtual bases.
+
+Wed Dec 28 08:31:00 1994 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (TYPEID): Strip top-level cv-qualifiers on typeid
+ expressions.
+ * gc.c (build_typeid): Likewise.
+
+Thu Dec 22 17:26:33 1994 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (build_up_reference): Fix breakage introduced on Nov 29,
+ don't assert on complex AGGR inits.
+
+Thu Dec 22 14:32:31 1994 Mike Stump <mrs@cygnus.com>
+
+ * method.c (build_overload_value): Handle pointer to members as
+ template arguments.
+
+Thu Dec 22 13:09:07 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (unary_complex_lvalue): Don't call sorry if we know how
+ to do take the address of a data member for a pointer to data
+ member.
+
+Thu Dec 22 10:04:19 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (grokdeclarator): Use the typedef name for linkage if the
+ type doesn't otherwise have a name.
+
+ * decl2.c (grokfield): Likewise.
+
+ * class.c (finish_struct): Since we reuse the TYPE_DECL for the
+ DECL_NAME of enums, structs and classes, we have to avoid trying to
+ put it in the TYPE_FIELDS again.
+
+Wed Dec 21 11:07:05 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (check_classfn): Ignore this parameter on static functions
+ when checking to see if we match.
+
+Tue Dec 20 17:47:02 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (unary_complex_lvalue): Handle address of non-left most
+ pointers to members by calling get_delta_difference.
+
+Mon Dec 19 22:40:53 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (check_classfn): Don't use decls_match yet, as it modifies
+ static functions to early.
+
+Thu Dec 19 22:37:48 1994 Mike Stump <mrs@cygnus.com>
+
+ * method.c (make_thunk): Handle encoding of positive thunk offsets.
+
+Sat Dec 17 13:29:50 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * Make-lang.in (.PHONY): Tell GNU make C++ and c++ are phony targets.
+
+Thu Dec 15 16:32:12 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (check_classfn): Use decls_match to check if this has
+ already been declared, as the DECL_ASSEMBLER_NAME may have been
+ changed via asm("new_name").
+ * decl.c (decls_match): Make public.
+
+Thu Dec 15 15:17:55 1994 Mike Stump <mrs@cygnus.com>
+
+ * *.[chy] (expand_aggr_init) Add fourth argument to handle
+ distinction between = init and (init) style of initializations.
+ * *.[chy] (finish_decl): Add fifth argument to to handle
+ distinction between = init and (init) style of initializations.
+
+Tue Dec 13 19:16:05 1994 Mike Stump <mrs@cygnus.com>
+
+ Fix some random `explicit' bugs.
+
+ * cvt.c (convert_to_reference): Add third parameter to
+ convert_force.
+ (convert_force): Likewise.
+ * call.c (build_method_call): Likewise.
+ * decl2.c (setup_vtbl_ptr): Likewise.
+ * init.c (expand_virtual_init): Likewise.
+ (build_member_call): Likewise.
+ (build_delete): Likewise.
+ (build_vbase_delete): Likewise.
+ * typeck.c (build_component_addr): Likewise.
+ (build_c_cast): Likewise.
+ (build_modify_expr): Likewise.
+ * cp-tree.h (CONV_NONCONVERTING): Likewise. Add so that we can
+ distinguish the context in which the conversion appears. Add thrid
+ argument to build_c_cast.
+ * cvt.c (cp_convert): Pass whether or not we want to consider
+ non-converting constructors down to build_method_call.
+ * decl2.c (reparse_absdcl_as_casts): Add third argument to
+ build_c_cast.
+ * gc.c (build_m_desc): Likewise.
+ * init.c (build_new): Likewise.
+ * parse.y (expr_no_commas): Likewise.
+ (primary): Likewise.
+ * typeck.c (build_x_function_call): Likewise.
+ (build_static_cast): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_const_cast): Likewise.
+ (build_c_cast): Likewise.
+ (build_ptrmemfunc): Likewise.
+ * typeck2.c (build_functional_cast): Likewise.
+ * init.c (expand_aggr_init): Added LOOKUP_ONLYCONVERTING to
+ expand_aggr_init_1 as inits are converted to the destination type.
+
+Tue Dec 13 16:18:57 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * Make-lang.in (cc1plus): Depends on c-pragma.o.
+
+ * Makefile.in (OBJ{DEP,}S): Add ../c-pragma.o.
+
+ * lex.c (check_newline): If the #pragma is not recognized by g++,
+ try machine-specific ones too.
+ (handle_sysv_pragma): Copied from c-lex.c.
+
+Mon Dec 12 23:53:06 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Fix Dec 6th change, build_new likes a
+ reference better.
+
+Mon Dec 12 18:01:00 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_binary_op): Lose checks on TYPE_PTRMEMFUNC_P with
+ IS_AGGR_TYPE, since now they will not both be set on the same type.
+
+ * pt.c (do_pending_expansions): Don't clear TREE_PUBLIC on
+ instantiations controlled by -fexternal-templates.
+
+ * decl.c (duplicate_decls): Don't complain about different values of
+ __attribute__ ((const)) and ((noreturn)).
+
+Fri Dec 9 18:17:37 1994 Doug Evans <dje@cygnus.com>
+
+ * Makefile.in (BISONFLAGS): Delete --yacc.
+ (PARSE_H): Depend on $(PARSE_C), for parallel makes.
+ (PARSE_C): Undo last patch.
+
+Fri Dec 2 10:44:36 1994 Mike Stump <mrs@cygnus.com>
+
+ * Makefile.in (BISONFLAGS): Add --yacc so that output winds up in
+ y.tab.c.
+
+Thu Dec 8 17:39:46 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (finish_decl): Don't call obscure_complex_init for decls
+ of indeterminate size.
+
+Wed Dec 7 16:49:22 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (obscure_complex_init): Function to tweak the decl to
+ prevent expand_decl from tring to initialize it.
+ (finish_decl): Use it rather than writing the same code in three
+ different places.
+
+ * parse.y (bad_parm): Stop trying to support parms without types.
+
+Wed Dec 7 12:06:56 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (grokfield): Make asm specs on static member functions
+ work.
+
+Tue Dec 6 15:43:20 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Make a copy of the thrown object.
+
+Tue Dec 6 14:16:34 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y: : has lower precedence than =.
+
+Tue Dec 6 12:46:17 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (pushdecl): Use DECL_NAME of VAR_DECLs to avoid namespace
+ manglings.
+ (grokvardecl): Add namespace into variable name.
+
+Tue Dec 6 11:26:55 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (current_namespace_id): New routine to transform a simple
+ name into a name in a namespace.
+ * decl.c (grokdeclarator): Use it.
+ * decl2.c (get_namespace_id): Find the name of the current
+ namespace.
+ (push_namespace, pop_namespace): Complete out missing
+ functionality.
+
+Mon Dec 5 17:11:51 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (finish_struct): Don't use LONG_LONG_TYPE_SIZE, as it may
+ not be defined. Fix warning message for enums and restore warning
+ for non-enums.
+
+ * decl2.c (push_namespace): Dummy function.
+ (pop_namespace): Likewise.
+ (do_namespace_alias): Likewise.
+ (do_using_decl): Likewise.
+ (do_using_directive): Likewise.
+
+ * parse.y: New token NSNAME for namespace names.
+ (extdef): Add namespace, using definitions.
+ (using_decl): New rule for using declarations.
+ (any_id): New rule for identifiers with any degree of scoping.
+ (identifier): Add NSNAME.
+ (notype_identifier): Likewise.
+ (component_decl): Add using_decl.
+ (nested_name_specifier): Add NSNAME SCOPE.
+
+ * typeck.c (convert_for_assignment): Handle conversions between
+ enums and bool.
+
+ * decl.c (duplicate_decls): Only propagate DECL_MAIN_VARIANT on
+ FUNCTION_DECLs.
+
+Mon Dec 5 13:03:16 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (finish_struct): Give an error if one tries to declare a
+ bit-field's size greater than a long long, as the backend will dump.
+ It is not an error to declare an enum bit-field greater than its
+ precision. Warn if an enum bit-field is too small to hold all
+ its values.
+
+Mon Dec 5 11:41:50 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (convert_for_assignment): Use cp_convert instead of
+ convert so that we don't get static casts.
+
+Sun Dec 4 11:59:01 1994 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (cp_convert): Don't complain about int->enum conversion if
+ we are doing static casts.
+
+Fri Dec 2 18:32:41 1994 Mike Stump <mrs@cygnus.com>
+
+ * error.c (dump_expr): Do something more intelligent with SAVE_EXPRs
+ when dumping expressions in error messages.
+
+Fri Dec 2 17:04:27 1994 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_dynamic_cast): Change interface to libg++, ensure that
+ the return type is the right type, and make references work.
+
+Fri Dec 2 16:36:43 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (poplevel): Don't be confused by function-scope
+ declarations of non-nested functions.
+ (duplicate_decls): Propagate DECL_MAIN_VARIANT.
+ (pushdecl): Use duplicate_decls to copy info from old decl into new
+ function-scope one rather than doing it here.
+
+ * decl2.c (mark_inline_for_output): Deal with the DECL_MAIN_VARIANT
+ of this decl, in case this is a function-scope declaration.
+
+ * decl.c (finish_enum): Make sure that the type has the right
+ precision when we call fixup_*_type.
+
+Tue Nov 29 19:12:07 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (build_up_reference): Strip superfluous NOP_EXPRs; we do
+ want to build up references to rvalues if possible.
+ (cp_convert): Stick on a NOP_EXPR when converting to the same type.
+
+Tue Nov 29 11:28:59 1994 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (maybe_raises): Handle throw ().
+ * parse.y (ansi_raise_identifier): grok type-ids in exception
+ specifications.
+ * tree.c (build_exception_variant): Use list compare to check if
+ two exception specifications match.
+ * decl.c (duplicate_decls, bad_specifiers): Enhance wording on error
+ messages.
+ * call.c (build_method_call): Remove TREE_RAISES.
+ * cvt.c (convert_to_aggr): Likewise.
+ * typeck.c (build_function_call_real, convert_arguments): Likewise.
+ * init.c (expand_aggr_init_1): Likewise.
+
+Tue Nov 29 09:50:39 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Add support for m68k and mips exception handling
+ support.
+
+Tue Nov 29 08:48:33 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_end_all_catch): Throw into outer context, if we
+ fall off end of catch handlers.
+
+Mon Nov 28 16:44:41 1994 Mike Stump <mrs@cygnus.com>
+
+ * Makefile.in: Make is easier to decide where parse.[ch] will be
+ built.
+
+Thu Nov 17 20:11:24 1994 Doug Evans <dje@cygnus.com>
+
+ * cp/Make-lang.in (CXX_INSTALL_NAME) Use program_transform_name.
+ (GXX_INSTALL_NAME) Likewise.
+ (CXX_CROSS_NAME) Use program_transform_cross_name.
+ (GXX_CROSS_NAME) Likewise.
+ (c++.install-man): Use program_transform_name on g++.1.
+ (c++.uninstall): Likewise.
+
+Mon Nov 28 13:53:03 1994 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (THROW): Fix precedence of throw expressions.
+
+Mon Nov 28 13:15:16 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_unary_op): Allow promotions from bool to int on
+ unary ~.
+
+Sun Nov 27 00:16:21 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (build_overload_name): Use DECL_ASSEMBLER_NAME for
+ classes when appropriate.
+ (build_overload_nested_name): When dealing with a function context,
+ use ASM_FORMAT_PRIVATE_NAME to tweak the name of the function to
+ avoid conflicts between local classes of the same name.
+
+Wed Nov 23 17:59:42 1994 Mike Stump <mrs@cygnus.com>
+
+ * gxx.gperf, parse.y, lex.h, hash.h, lex.c (init_lex), delc.c
+ (duplicate_decls, grokdeclarator), cp-tree.h: Add support for
+ `explicit'.
+ * cvt.c (convert_to_reference, cp_convert, build_type_conversion_1,
+ build_type_conversion): Use LOOKUP_ONLYCONVERTING in
+ build_method_calls so that non-converting constructors are not used.
+ * call.c (build_method_call): If we shouldn't use a non-converting
+ constructor, then don't.
+
+Wed Nov 23 14:46:56 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Don't try to synthesize methods yet.
+
+Tue Nov 22 12:45:21 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (push_template_decls): Create CONST_DECLs for template
+ constant parameters, not VAR_DECLs.
+
+Sat Nov 19 15:28:31 1994 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Can shorten shift only if
+ shift count is less than size in bits of arg0.
+
+Thu Nov 17 15:30:50 1994 Mike Stump <mrs@cygnus.com>
+
+ * gxx.gperf, hash.h, lex.c (init_lex, real_yylex), parse.y: Add new
+ ANSI keywords and, and_eq, bitand, bitor, explicit, namespace, not,
+ not_eq, or, or_eq, typename, using, xor, xor_eq to g++. Still need
+ to add support for explicit, namespace, typename, and using, support
+ for the rest is already in.
+
+Fri Nov 4 19:04:18 1994 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (get_bad_cast_node): New routine to support compile time
+ throws of bad_cast.
+ * gc.c (build_dynamic_cast): Support throwing of bad_cast at compile
+ time.
+
+Fri Nov 4 11:12:00 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Add hppa support.
+
+Fri Nov 4 10:50:50 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Add rs6000 support.
+
+Thu Nov 3 14:24:23 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (do_unwind): Add i[34]86 support.
+
+Thu Nov 3 00:10:46 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (do_pending_expansions): Unset TREE_PUBLIC on implicit
+ instantiations.
+
+Wed Nov 2 15:08:24 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * decl.c (finish_function): Emit types used in method parameters
+ into symbol table.
+
+Wed Nov 2 15:05:47 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (process_template_parm): Allow pointer to member function
+ template parameter types.
+ (uses_template_parms): Handle pointer to member function
+ CONSTRUCTORs.
+
+ * g++.c (main): Cast first argument of bzero to (char *).
+ Pass -lstdc++ instead of -lg++ unless we are invoked as 'g++'.
+
+Mon Oct 31 14:50:48 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * gc.c (build_dynamic_cast): rewrite to make it work.
+ * class.c (finish_vtbls): build more vtables if flag_rtti is on.
+ * class.c (modify_all_direct_vtables): ditto.
+ * init.c (expand_direct_vtbls_init): expand more vtables if
+ flag_rtti is on.
+ * decl.c (init_type_desc): add default return.
+
+Tue Oct 25 17:13:09 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * tree.c (debug_binfo): get rid of the initial size entry of
+ vtable.
+ * cp-tree.h: change flag_dossier to flag rtti, define type
+ descriptor type nodes.
+ * decl.c (init_type_desc): new function to initialize type
+ descriptor type nodes.
+ * decl.c (record_builtin_type): change flag_dossier to flag_rtti.
+ * lex.c (init_lex): ditto.
+ * decl.c : change variable flag_dossier to flag_rtti.
+ * decl.c (duplicate_decls): get rid initial size entry of vtable.
+ * decl.c (hack_incomplete_structures): take out assert 164.
+ * search.c (get_abstract_virtuals_1): ditto.
+ * search.c (dfs_init_vbase_pointers): change CLASSTYPE_DOSSIER to
+ CLASSTYPE_RTTI.
+ * parse.y: ditto.
+ * class.c (prepare_fresh_vtable): for virtual bases, get right
+ offset.
+ * class.c (add_virtual_function): change flag_dossier to
+ flag_rtti.
+ * class.c (modify_one_vtable): modify the right rtti entry.
+ * class.c (override_one_vtable): get rid of size entry.
+ * class.c (finish_struct): change flag_dossier to flag_rtti, and
+ build extra vtables, build type descriptors for polymorphic
+ classes.
+ * gc.c (build_headof): make headof() works correctly with new
+ rtti.
+ * gc.c (build_typeid): make this function work with new rtti.
+ * gc.c (get_typeid): make this function work with new rtti.
+ * gc.c (build_bltn_desc): new function for new rtti.
+ * gc.c (build_user_desc): ditto.
+ * gc.c (build_class_desc): ditto.
+ * gc.c (build_ptr_desc): ditto.
+ * gc.c (build_attr_desc): ditto.
+ * gc.c (build_func_desc): ditto.
+ * gc.c (build_ptmf_desc): ditto.
+ * gc.c (build_ptmd_desc): ditto.
+ * gc.c (build_t_desc): ditto.
+ * gc.c : comment out old build_t_desc, build_i_desc, build_m_desc.
+
+Tue Oct 25 13:37:41 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (convert_harshness): Check for TREE_UNSIGNED differences
+ after checking for integral conversions.
+
+Wed Nov 30 19:13:50 1994 Mike Stump <mrs@cygnus.com>
+
+ * Version 2.6.3 released.
+
+Thu Nov 17 10:56:50 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck2.c (build_m_component_ref): Check the basetype of the
+ member pointer against the main variant of the object type.
+
+Mon Nov 14 14:21:52 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (convert_to_reference): Make sure that the original expr
+ gets its type back when converting a reference.
+
+ * method.c (build_overload_name): Clear numeric_outputed_need_bar here.
+ (build_decl_overload): Instead of here.
+
+Tue Nov 8 17:11:24 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (cp_convert): Don't build a TARGET_EXPR if we're not in a
+ function.
+
+ * typeck.c (convert_for_initialization): Handle initialization from
+ a TARGET_EXPR.
+
+Sun Nov 6 01:34:24 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (lookup_nested_type_by_name): Fix list-walking logic.
+ (tsubst): When replacing a TEMPLATE_TYPE_PARM, propagate
+ TYPE_READONLY and TYPE_VOLATILE from the argument.
+ (unify): When unifying with a TEMPLATE_TYPE_PARM, remove cv-quals
+ present in parm from arg.
+ (type_unification): Strip REFERENCE_TYPE from the argument type.
+ (unify): Don't strip REFERENCE_TYPE from the argument type.
+
+Sat Nov 5 22:42:15 1994 Greg McGary <gkm@magilla.cichlid.com>
+
+ * pt.c (do_type_instantiation): Check to see if there's a
+ IDENTIFIER_TEMPLATE on a class before calling
+ instantiate_member_templates().
+
+Sat Nov 12 06:35:42 1994 Mike Stump <mrs@cygnus.com>
+
+ * Version 2.6.2 released.
+
+Thu Nov 3 18:48:19 1994 Paul Eggert <eggert@twinsun.com>
+
+ * Makefile.in (spew.o, lex.o, pt.o):
+ Depend on $(srcdir)/parse.h, not parse.h.
+
+Tue Nov 1 19:19:41 1994 Mike Stump <mrs@cygnus.com>
+
+ * Version 2.6.1 released.
+
+Sun Oct 23 13:19:55 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c: Declare flag_access_control.
+ (struct lang_f_options): Add access-control.
+ * expr.c (cplus_expand_expr, NEW_EXPR): Unset flag_access_control
+ for the call to expand_aggr_init to copy the object out of the
+ pcc_struct_return slot.
+ * search.c (compute_access): if (!flag_access_control) return
+ access_public.
+
+Fri Oct 21 00:32:54 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * lex.c (cons_up_default_function): Don't try to defer method
+ synthesis now.
+
+ * decl.c (init_decl_processing): Use __pure_virtual for abort_fndecl
+ instead of abort, since the OSF/1 dynamic linker doesn't like to see
+ relocation entries for abort.
+
+ * tree.c (array_type_nelts_total): Use sizetype, not
+ integer_type_node.
+ (array_type_nelts_top): Likewise.
+
+Thu Oct 20 15:48:27 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (grokdeclarator): Added handling for catch parameters
+ (CATCHPARM).
+ * except.c (expand_start_catch_block): Use the new CATCHPARM context
+ instead of NORMAL.
+ * except.c (expand_throw): Don't let convert_to_reference complain
+ about what we are doing.
+
+Thu Oct 20 12:55:24 1994 Jim Wilson <wilson@cygnus.com>
+
+ * method.c (emit_thunk): Call instantiate_virtual_regs.
+
+Wed Oct 19 14:15:33 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_exception_blocks): Make sure throw code doesn't
+ get put in function that won't be output.
+
+Mon Oct 17 18:03:15 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (init_decl_processing): Make alloca a builtin.
+
+Thu Oct 27 21:10:25 1994 Craig Burley <craig@burley>
+
+ * g++.c (main): Only decrement "added" and set "library" to
+ NULL when "library" != NULL (just like 940829 fix).
+
+Mon Oct 17 15:56:11 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_start_catch_block): Make sure the false label
+ gets onto the permanent obstack, as it is used for the exception
+ table.
+
+Fri Oct 14 18:54:48 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (modify_one_vtable): Since the DECL_CONTEXT of fndecl can
+ be set just below, use current_fndecl instead.
+
+Fri Oct 14 15:12:22 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (expand_aggr_vbase_init_1): Don't call expand_aggr_init_1
+ with LOOKUP_SPECULATIVELY.
+ (expand_default_init): Abort if build_method_call returns NULL_TREE.
+
+ * typeck.c (build_modify_expr): Don't just build a MODIFY_EXPR if
+ the rhs is a TARGET_EXPR.
+
+ * parse.y (left_curly): Anonymous types are not affected by #pragma
+ interface/implementation.
+
+ * method.c (synthesize_method): Don't call setup_vtbl_ptr for the
+ default constructor if it isn't needed.
+
+ * lex.c (cons_up_default_function): Do synthesize methods for
+ anonymous types if necessary.
+
+Thu Oct 13 17:44:55 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (build_decl_overload): Set numeric_outputed_need_bar to 0.
+
+Wed Oct 12 13:27:57 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_modify_expr): Understand how to copy an aggregate.
+
+ * init.c (expand_default_init): Likewise. Also remove some of the
+ crufty code that assumes methods will not be synthesized properly.
+
+ * lex.c (cons_up_default_function): If the containing type has no
+ name, these functions should never need to be called, so just
+ declare them.
+
+ * lex.c (real_yylex): Use HOST_BITS_PER_WIDE_INT to determine the
+ bitmask for lexing character constants.
+
+ * call.c (build_method_call): Disable code that tries to do tricky
+ stuff with a default parameter that is a constructor call, but
+ actually does other tricky stuff that breaks things.
+
+Wed Oct 12 16:14:01 1994 Benoit Belley <belley@cae.ca>
+
+ * decl.c (finish_enum): Disable code which forces enums to be signed,
+ since this conflicts with their use as bitfields. type_promotes_to
+ handles promotion of enums of underlying unsigned types to signed
+ integer types.
+
+Wed Oct 12 13:24:03 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (type_promotes_to): Also promote enums to long if
+ appropriate.
+
+ * typeck.c (default_conversion): Don't expect type_promotes_to to
+ return a main variant.
+
+Wed Oct 12 12:19:45 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_scoped_method_call): Don't lose side effects in the
+ object expression when calling a non-existent destructor.
+
+Fri Sep 2 19:05:21 1994 Rohan Lenard <rjl@iassf.easams.com.au>
+
+ * call.c (build_scoped_method_call): Remove erroneous error message
+ when destructor call is written as a scoped call.
+
+Tue Oct 11 23:48:31 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * various: Cast pointer arguments to bzero and bcopy to char *.
+
+Tue Oct 11 19:34:32 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (get_derived_offset): Added a type parameter to limit how
+ far up the CLASSTYPE_VFIELD_PARENT chain we search.
+ * class.c (modify_one_vtable, fixup_vtable_deltas): When forming the
+ offset to put into the vtable for the this parameter, make sure we
+ don't offset from a parent of the DECL_CONTEXT of the function.
+
+Tue Oct 11 16:10:52 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (do_function_instantiation): Set DECL_EXTERNAL and
+ TREE_STATIC when setting DECL_INTERFACE_KNOWN.
+ (do_type_instantiation): Likewise.
+
+ * lex.c (cons_up_default_function): Set DECL_INTERFACE_KNOWN,
+ DECL_EXTERNAL and TREE_STATIC as appropriate.
+
+ * decl2.c (finish_file): Also synthesize methods that don't have
+ DECL_EXTERNAL set. Set interface_unknown before doing so.
+
+ * decl.c (start_function): If DECL_INTERFACE_KNOWN is set on the
+ function decl, don't muck with TREE_PUBLIC and DECL_EXTERNAL.
+
+Mon Oct 10 00:56:53 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * lex.c (cons_up_default_function): Mark methods in a template class
+ as template instances. Store the values of interface_unknown and
+ interface_only for do_pending_inlines.
+ (do_pending_inlines): Use them.
+
+ * decl2.c (finish_file): If we haven't seen a definition of a
+ function declared static, make the decl non-PUBLIC so compile_file
+ can give an error.
+
+Sun Oct 9 02:42:29 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (do_build_copy_constructor): Handle anonymous unions.
+ (do_build_assign_ref): Likewise.
+ (largest_union_member): Move from lex.c.
+
+Sat Oct 8 14:59:43 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ Re-implement g++'s vague linkage independent of TREE_PUBLIC.
+ * pt.c (instantiate_member_templates): Lose redundant
+ -fexternal-templates handling.
+ (tsubst): Set TREE_PUBLIC and DECL_EXTERNAL on new decls. Don't set
+ TREE_STATIC or DECL_INTERFACE_KNOWN.
+ (do_pending_expansions): Predicate on DECL_INTERFACE_KNOWN instead
+ of DECL_EXTERNAL for explicit instantiations.
+ (do_function_instantiation): Do the new thing.
+ (do_type_instantiation): Likewise.
+ (instantiate_template): Deal with member templates defined in a .cc
+ file with -fexternal-templates.
+ * except.c (expand_exception_blocks): Use DECL_LINKAGE_KNOWN to
+ decide whether to stick builtin_throw here.
+ * decl2.c (import_export_inline): Predicate on DECL_INTERFACE_KNOWN
+ rather than TREE_PUBLIC. Generally fix rules.
+ (finish_file): Use DECL_INITIAL to determine whether or not a method
+ has been synthesized, rather than TREE_ASM_WRITTEN.
+ * decl.c (warn_extern_redeclared_static): Use DECL_PUBLIC instead of
+ TREE_PUBLIC.
+ (pushdecl): Likewise.
+ (duplicate_decls): Likewise. Deal with DECL_DECLARED_STATIC and
+ DECL_INTERFACE_KNOWN.
+ (redeclaration_error_message): Fix checking for conflicting linkage.
+ (define_function): Set DECL_INTERFACE_KNOWN.
+ (grokfndecl): Function decls are PUBLIC until we are sure about
+ their linkage. Set DECL_DECLARED_STATIC as needed.
+ (start_function): Deal with linkage. Move pushdecl after linkage
+ magic.
+ (finish_function): Don't set TREE_ASM_WRITTEN on discarded inlines.
+ * cp-tree.h (lang_decl_flags): Add interface_known and
+ declared_static.
+ (DECL_INTERFACE_KNOWN): New macro.
+ (DECL_DECLARED_STATIC): New macro.
+ (DECL_PUBLIC): New macro.
+
+ Clean up bogus use of TREE_PUBLIC.
+ * class.c (alter_access): Fix mistaken use of TREE_PUBLIC (it
+ doesn't correspond to TREE_PROTECTED and TREE_PRIVATE).
+ * init.c (do_friend): Don't arbitrarily set TREE_PUBLIC.
+
+Wed Oct 5 13:44:41 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_overload_call_real): Don't immediately do
+ array->pointer conversion.
+
+ * pt.c (type_unification): If not passing to a reference, strip
+ cv-quals. Also handle array->pointer conversion.
+
+Tue Oct 4 17:45:37 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't warn about applying const to a
+ const typedef or template type parameter.
+
+ * decl2.c (finish_file): Also synthesize methods after walking the
+ vtables. Ugly ugly ugly.
+
+Mon Oct 3 15:02:41 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * various: Remove lingering remnants of old exception handling code.
+
+ * decl2.c (finish_file): Synthesize methods before walking the
+ vtables, so that the vtables get emitted as needed.
+
+ * decl.c (shadow_tag): Remove obsolete code for pushing tags and
+ dealing with exceptions.
+
+Mon Oct 3 13:05:27 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * Make-lang.in (g++-cross): Depend upon version.o and $(LIBDEPS).
+
+Mon Oct 3 02:59:28 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (finish_file): Fix inline handling.
+
+Sun Oct 2 00:21:56 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grokdeclarator): Handle redundant scope even better.
+ ({push,pop}_cp_function_context): Take toplev parameter.
+
+ * method.c (synthesize_method): Pass toplev parameter to
+ {push,pop}_cp_function_context depending on decl_function_context
+ (fndecl).
+
+ * typeck.c (build_x_unary_op): Unary & on OFFSET_REFs is always the
+ built-in version.
+
+ * method.c (synthesize_method): Don't be confused by __in_chrg
+ parameter.
+
+ * class.c (popclass): Set C_C_D like start_function does.
+
+ * decl.c (grokdeclarator): Handle redundant scope better.
+
+ * parse.y (expr_or_declarator): Add '(' expr_or_declarator ')' rule.
+ (direct_notype_declarator): Likewise.
+ (complex_direct_notype_declarator): Remove it here.
+
+Sat Oct 1 21:42:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (resolve_offset_ref): Fix types used in resolving .*
+ expressions.
+
+Sat Oct 1 15:18:49 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ Beginnings of work to synthesize methods only when needed.
+ * call.c (build_method_call): Synthesize methods as necessary
+ (currently never necessary).
+ * class.c (popclass): Don't try to set C_C_D here, as it'll end up
+ on the wrong obstack.
+ * decl.c (push_cp_function_context): Mostly copied from
+ push_c_function_context.
+ (pop_cp_function_context): Similarly.
+ (finish_function): Reverse order of poplevel and pop_nested_class so
+ that current_class_decl is restored properly.
+ (start_function): Likewise.
+ (finish_function): Add parameter 'nested'. Don't call
+ permanent_allocation if (nested).
+ * various: Pass extra parameter to finish_function.
+ * decl2.c (finish_file): Reorganize end-of-file inline handling,
+ synthesizing methods as necessary.
+ * lex.c (cons_up_default_function): Call mark_inline_for_output.
+ Only synthesize methods immediately if #pragma implementation
+ (currently disabled).
+ (do_pending_inlines): Call synthesize_method.
+ * method.c (synthesize_method): New function; all method synthesis
+ goes through here. Calls do_build_assign_ref and
+ do_build_copy_constructor.
+ (build_default_constructor): Remove.
+ (build_dtor): Likewise.
+ (build_assign_ref): Rename to do_build_assign_ref and remove stuff
+ done by synthesize_method.
+ (build_copy_constructor): Similarly.
+
+Thu Sep 29 16:58:52 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (c_expand_return): Use magic so the backend can fixup the
+ assignment into the return register, so cleanups won't clobber it.
+
+Thu Sep 29 13:08:50 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * method.c (hack_identifier): Don't call assemble_external for
+ template decls.
+
+ * decl.c (finish_decl): Also end temporary allocation if the decl in
+ question has a type of error_mark_node.
+
+Wed Sep 28 21:45:00 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_modify_expr): When optimizing ?: on lhs, make sure
+ that if the ?: was a reference type, that the subparts will be also.
+
+Wed Sep 28 16:14:04 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * except.c (register_exception_table): Use Pmode, not PTRmode.
+
+Fri Sep 23 13:54:27 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (do_pending_inlines): Do method synthesis after the
+ pending_inlines have been reversed.
+
+Thu Sep 22 12:53:03 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl2.c (finish_file): Fix Brendan's fix: Only call
+ register_exception_table if there is a non-empty exception table.
+
+Thu Sep 22 12:03:46 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl2.c (finish_file): Only do register_exception_table if
+ -fhandle-exceptions is being used.
+
+Wed Sep 21 19:01:51 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * except.c (output_exception_table_entry): Simplify
+ by using assemble_integer.
+ (build_exception_table): Change to return a count.
+ Cleanup to use standard macros, instead of hard-wired
+ sparc asm format. Don't make __EXCEPTION_TABLE__ global.
+ (register_exception_table): New function. Generate call to builtin.
+ * decl2.c (finish_file): Call register_exception_table.
+ * cp-tree.h (build_exception_table): Fix prototype.
+
+Wed Sep 21 13:20:42 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * tree.c (break_out_calls): Don't try to duplicate the DECL_INITIAL.
+
+ * decl2.c (delete_sanity): Give an error at trying to delete a
+ function.
+
+Wed Sep 21 11:47:10 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (cons_up_default_function): Mark synthesized destructors
+ inline.
+
+ * decl.c (duplicate_decls): Ignore redeclarations of wchar_t as
+ something other than __wchar_t, complaining if -pedantic and not in
+ a system header.
+
+Tue Sep 20 09:43:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (xref_tag): Set up BINFO_INHERITANCE_CHAIN on base binfos
+ here.
+
+ * typeck.c (build_modify_expr): Require complete type after checking
+ for error_mark_node.
+
+ * call.c (build_method_call): Print parmtypes when complaining of
+ ambiguous call.
+
+ * typeck.c (build_modify_expr): Handle assignment to array from
+ non-array.
+
+ * decl.c (lookup_name_real): Deal with got_scope == error_mark_node.
+
+ * call.c (build_method_call): Don't bother with the exact match.
+
+Mon Sep 19 00:51:39 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (expand_aggr_init): If we munge the type of the variable,
+ also munge the type of the initializer.
+
+ * decl.c (grokdeclarator): Use <= when comparing to RID_LAST_MODIFIER.
+ (init_decl_processing): Push artificial declaration of wchar_t so
+ people don't have to declare it before they can use it.
+
+ * error.c (cp_line_of): return lineno in lieu of 0.
+
+ * typeck.c (convert_for_assignment): Handle conversion of pmfs to
+ int and bool.
+ (build_component_ref): Fold the COMPONENT_REF in case it can be
+ reduced.
+
+ * typeck2.c (store_init_value): Don't pedwarn about non-constant
+ bracketed initializers for automatic variables.
+
+Sun Sep 18 10:12:12 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * error.c (dump_decl): Don't say `typedef enum foo foo'.
+
+ * decl.c (start_decl): Don't set TREE_PUBLIC on template decls just
+ because they're affected by #pragma i/i. We'll deal with that when
+ they get instantiated.
+
+ * typeck.c (build_unary_op): Clean up cruft in ADDR_EXPR case.
+
+ * class.c (instantiate_type): Set TREE_CONSTANT on instantiated
+ ADDR_EXPRs if appropriate.
+
+ * decl.c (build_ptrmemfunc_type): Unset IS_AGGR_TYPE on pmf types.
+
+ * typeck.c (build_ptrmemfunc): Handle &overloaded_method as an
+ initializer properly.
+ * typeck2.c (digest_init): Likewise.
+
+ * tree.c (cp_build_type_variant): Like c_build_type_variant, except
+ it uses build_cplus_array_type.
+ * *.c: Use cp_build_type_variant instead of c_build_type_variant.
+
+ * pt.c (do_type_instantiation): Don't try to instantiate nested
+ enums.
+
+Tue Sep 13 10:56:58 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (build_up_reference): Handle preincrement and predecrement
+ properly.
+
+Tue Sep 13 09:51:59 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (finish_decl): Only lay out the rtl for DECL if it is, in
+ fact, static.
+
+Mon Sep 12 14:40:30 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (finish_decl): Lay out the rtl for DECL before doing
+ grok_reference_init, in case it's static.
+
+Mon Sep 12 12:45:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Don't synthesize constructors if the
+ class has a field with the same name as the class. Don't die on
+ classes with no constructors or destructors. Don't die if the head
+ and tail of the class are in different files.
+
+ * decl.c (grokdeclarator): Don't treat a function pointer field
+ with the same name as the class as a constructor.
+
+Fri Sep 9 13:17:00 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_c_cast): Pull constant values out of their
+ variables here.
+
+ * decl.c (duplicate_decls): Only propagate DECL_CHAIN in
+ FUNCTION_DECLs and TEMPLATE_DECLs.
+
+Thu Sep 8 10:07:48 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (duplicate_decls): Propagate DECL_CHAIN in all DECLs that
+ have it.
+
+ * pt.c (unify): REALs and INTEGERs only unify with their own genus.
+ (instantiate_member_templates): Don't muck with DECL_EXTERNAL and
+ TREE_PUBLIC unless -fexternal-templates.
+
+Wed Sep 7 13:17:10 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (do_type_instantiation): Call instantiate_member_templates.
+ Deal with specializations.
+ (tsubst): Don't stick the mangled name in DECL_NAME for function
+ instantiations. Don't push them, either.
+
+ * decl2.c (grokfield): Move code for generating the
+ DECL_ASSEMBLER_NAME for static members from here.
+ * method.c (build_static_name): To here.
+ * decl.c (grokvardecl): Call build_static_name.
+ (duplicate_decls): Keep old DECL_ASSEMBLER_NAME.
+
+Mon Sep 5 12:49:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): if -Wsynth, warn when selecting
+ synthesized op= over user-supplied one cfront would select.
+ * decl2.c (lang_decode_option): Handle -Wsynth.
+
+Fri Sep 2 15:11:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (finish_enum): Overhaul to fix several bugs.
+ (start_enum): Disable useless code.
+
+Thu Sep 1 16:04:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (c_expand_return): Warn about returning a reference to a
+ temporary.
+ (convert_arguments): Increment argument counter when using default
+ arguments, too.
+
+Wed Aug 31 14:29:22 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (finish_decl): If the type of decl is error_mark_node,
+ don't bother trying to do anything.
+
+ * typeck.c (convert_for_initialization): If the rhs contains a
+ constructor call, pretend the lhs type needs to be constructed.
+
+ * init.c (expand_default_init): If we stick the object inside the
+ initializer, mark the initializer used.
+
+Tue Aug 30 13:50:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * method.c (build_assign_ref): return *this;
+ (build_assign_ref): Fix base assignment order.
+ (build_copy_constructor): Fix member init order.
+
+Mon Aug 29 13:54:39 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * g++.c (main): Remember to clear out SAW_SPECLANG after we see
+ its argument.
+
+Sat Aug 27 09:36:03 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * method.c (build_copy_constructor): Also copy virtual bases.
+
+Fri Aug 26 17:05:15 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (do_pending_inlines): Clear out pending_inlines before doing
+ any synthesis. Also first set deja_vu on all pending_inlines.
+
+ * method.c (build_assign_ref): Use build_member_call to invoke base
+ operator=, rather than build_modify_expr. And use
+ build_reference_type instead of TYPE_REFERENCE_TO.
+ (build_copy_constructor): Use TYPE_NESTED_NAME to identify the
+ basetype.
+
+ * decl2.c (grokfield): Don't complain about undefined local class
+ methods.
+
+ * class.c (finish_struct): Don't try to synthesize methods here.
+ * lex.c (do_pending_inlines): Instead, synthesize them here.
+ (init_lex): Initialize synth_obstack.
+ (cons_up_default_function): Stick synthesis request on
+ pending_inlines.
+
+Fri Aug 26 12:24:14 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c (build_method_call) [PCC_STATIC_STRUCT_RETURN]: Also
+ accept an RTL_EXPR in what we're about to use for the instance,
+ since anything which would end up with pcc_struct_return set
+ inside cplus_expand_expr.
+
+ * cp-tree.h (cons_up_default_function): Note change of prototype.
+
+Thu Aug 25 23:05:30 1994 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * class.c (finish_struct): Undid change from Aug 21 testing
+ CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING.
+ * parse.y (left_curly): Likewise, undid change from Aug 21.
+ * decl.c (xref_tag): Undid change from Aug 21, set
+ CLASSTYPE_INTERFACE correctly, and added comments.
+
+Thu Aug 25 00:36:31 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Rework approach to synthesized methods; don't go through the parser
+ anymore.
+ * class.c (finish_struct): Use new synthesis approach.
+ * lex.c (cons_up_default_function): Now just creates declaration,
+ not code.
+ (largest_union_member): #if 0 out.
+ (default_assign_ref_body): Likewise.
+ (default_copy_constructor_body): Likewise.
+ * method.c (build_default_constructor): New function to synthesize X().
+ (build_copy_constructor): Synthesize X(X&).
+ (build_assign_ref): Synthesize X::operator=(X&).
+ (build_dtor): Synthesize ~X().
+
+ * error.c (cp_line_of): If we're dealing with an artificial
+ TYPE_DECL, look at the type instead.
+
+Wed Aug 24 11:11:50 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (sort_member_init): Check warn_reorder.
+ * decl2.c (lang_decode_option): Handle -W{no-,}reorder.
+
+ * cp-tree.h (CLASSTYPE_SOURCE_LINE): New macro.
+ * error.c (cp_line_of): Use CLASSTYPE_SOURCE_LINE for aggregates.
+ * class.c (finish_struct): Set CLASSTYPE_SOURCE_LINE.
+
+Tue Aug 23 09:28:35 1994 Mike Stump <mrs@cygnus.com>
+
+ * error.c (dump_decl): Improve wording, so that error messages
+ dont't read template<, class foo>...
+
+Mon Aug 22 15:30:51 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (label_colon): Also match a TYPENAME as a label name,
+ since they may have declared a class by that name but have also
+ tried to have a local label under the same name.
+
+ * pt.c (coerce_template_parms): Call cp_error, not cp_error_at,
+ for the message so they know at what point it was instantiated.
+
+Sun Aug 21 23:07:35 1994 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and
+ CLASSTYPE_VTABLE_NEEDS_WRITING for signatures up to left_curly time.
+ * decl.c (xref_tag): Move setting of CLASSTYPE_INTERFACE and
+ CLASSTYPE_VTABLE_NEEDS_WRITING for signatures down to left_curly time.
+ * parse.y (left_curly): New final resting place for setting
+ CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING for signatures.
+
+ * class.c (finish_struct): Don't test for function/field name
+ conflicts in signatures, since all the fields are compiler-constructed.
+
+Fri Aug 19 14:04:47 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * method.c (build_overload_nested_name): in qualified name
+ mangling, the template with value instantiation will have numeric
+ at end and may mixed with the name length of next nested level.
+ Add a '_' in between.
+ * method.c (build_overload_name): ditto.
+ * method.c (build_overload_identifier): ditto.
+
+Thu Aug 18 16:24:43 1994 Mike Stump <mrs@cygnus.com>
+
+ * error.c (dump_decl): Handle NULL args.
+
+Thu Sep 29 16:15:36 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
+
+ * g++.c: Rework last change so it's done like collect.c (and
+ gcc.c).
+
+Wed Sep 14 10:17:27 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
+
+ * g++.c: Include <sys/errno.h> in case `errno' is a macro
+ as permitted by ANSI C.
+
+Thu Aug 18 12:48:09 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and
+ CLASSTYPE_VTABLE_NEEDS_WRITING up to left_curly time.
+ * decl.c (xref_tag): Move setting of CLASSTYPE_INTERFACE and
+ CLASSTYPE_VTABLE_NEEDS_WRITING down to left_curly time.
+ * parse.y (left_curly): New final resting place for setting
+ CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING.
+
+Thu Aug 11 11:32:42 1994 H.J. Lu <hjl@nynexst.com>
+
+ * g++.c (main): Only decrement "added" and set "library" to
+ NULL when "library" != NULL.
+
+Sat Aug 13 00:14:52 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't set TREE_PUBLIC on a function decl
+ just because its class has a known interface.
+ (decls_match): Deal with new format of template parms.
+
+ * lex.c (cons_up_default_function): Don't play with TREE_PUBLIC and
+ DECL_EXTERNAL here.
+
+Fri Aug 12 01:55:15 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (pushtag): SET_DECL_ARTIFICIAL on gratuitous typedefs.
+ (xref_defn_tag): Likewise.
+ (pushdecl): Only allow artificial typedefs to be shadowed.
+
+ * init.c (emit_base_init): Pass the right binfos to
+ expand_aggr_init_1.
+
+ * class.c (delete_duplicate_fields_1): Make it work right.
+ (finish_struct): Catch function/field name conflict.
+
+ * decl2.c (check_classfn): Pass the function to cp_error, not just
+ the name.
+
+ * init.c (sort_member_init): Warn when order of member initializers
+ does not match order of member declarations.
+ (emit_base_init): Call expand_aggr_init_1 with LOOKUP_PROTECT.
+
+ * error.c (dump_expr): Handle lists of functions.
+
+ * decl.c (start_function): #pragma interface only affects functions
+ that would otherwise be static.
+ (finish_decl): Don't warn about an unused variable if it has both
+ constructor and destructor, since the 'resource allocation is
+ initialization' idiom is relatively common.
+
+ * typeck.c (comp_target_types): Don't handle TEMPLATE_TYPE_PARMs.
+ (comp_target_parms): Likewise.
+ (compparms): Never consider default parms.
+ (common_base_type): Don't choose a virtual baseclass if there is a
+ more derived class in common.
+ (build_conditional_expr): If pedantic, pedwarn about conversion to
+ common base in conditional expr.
+
+ * class.c (instantiate_type): Handle template instantiation better.
+
+ * typeck.c (convert_arguments): Don't try to get tricky and convert
+ to int directly when PROMOTE_PROTOTYPES is set, as it breaks
+ user-defined conversions.
+
+ * lex.c (check_for_missing_semicolon): Also give error at end of
+ file.
+
+ * call.c (build_method_call): Don't promote arrays to pointers here.
+
+ * typeck.c (convert_arguments): Don't require the actual parameter
+ to be of a complete type if the formal parameter is a reference.
+
+Thu Aug 11 15:21:40 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Soften 'static' on member function error
+ to pedwarn.
+
+ * init.c (build_new): Don't automatically save rval.
+ (build_offset_ref): Do field lookup with proper basetype_path.
+
+Thu Aug 11 12:46:54 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * errfn.c (cp_silent): Declare to mark when we should avoid
+ emitting warnings and errors.
+ (cp_error): Check it.
+ (cp_warning): Likewise.
+ (cp_pedwarn): Likewise.
+ (cp_compiler_error): Likewise.
+ (cp_error_at): Likewise.
+ (cp_warning_at): Likewise.
+ (cp_pedwarn_at): Likewise.
+ * call.c (compute_conversion_costs): Set CP_SILENT when we start
+ out, and make sure we turn it off before we leave.
+
+Thu Aug 11 00:02:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (grok_array_decl): Try computing *(A+B) if neither
+ argument is obviously an array.
+
+Wed Aug 10 15:32:04 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (c_expand_start_case): Do cleanups here.
+
+ * parse.y (xcond): Do bool conversion here, too.
+ (simple_stmt, SWITCH case): Don't do cleanups here.
+
+ * decl.c (duplicate_decls): Don't treat builtins that have been
+ explicitly declared specially.
+
+Tue Aug 9 01:16:09 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * tree.c (make_deep_copy): Support copying pointer, reference,
+ function, array, offset and method types.
+
+ * decl.c (init_decl_processing): Mark exit and abort as
+ BUILT_IN_NONANSI so that duplicate_decls is kinder about
+ redeclaration.
+ (duplicate_decls): Don't give two errors for redeclaring a C
+ function with the same parms but a different return type.
+
+ * parse.y (paren_cond_or_null): Do cleanup and bool conversion here.
+ (condition): Instead of here.
+ (simple_stmt, SWITCH case): Also do cleanup here.
+
+ * decl2.c (finish_anon_union): Only break out FIELD_DECLs.
+
+ * call.c (build_method_call): Don't throw away the side effects of
+ the object in a call to a non-existent constructor.
+ * parse.y (primary): Likewise.
+
+ * method.c (build_decl_overload): Oop.
+
+ * decl2.c (lang_decode_option): Deal with flag_no_nonansi_builtin,
+ warn about uselessness of specifying -fansi-overloading.
+
+ * method.c (build_decl_overload): Treat any non-member new with one
+ parameter as __builtin_new.
+
+ * decl.c (init_decl_processing): Setup built-in meanings of exit,
+ _exit and abort.
+
+Mon Aug 8 15:03:30 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * error.c (dump_readonly_or_volatile): Put a space between const and
+ volatile if both apply.
+
+ * init.c (perform_member_init): Clean up after this initialization.
+ (emit_base_init): Clean up after each base init, not after all have
+ been done.
+ (expand_aggr_vbase_init_1): Clean up after this init.
+
+Sun Aug 7 14:55:05 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Deal with destroying references.
+
+ * parse.y (condition): Do bool_truthvalue_conversion here.
+ (paren_expr_or_null): And here.
+ (simple_if): Not here.
+ (simple_stmt): Or here.
+
+Sat Aug 6 22:29:45 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (paren_expr_or_null): Wrap the expression in a
+ CLEANUP_POINT_EXPR.
+ (condition): Likewise.
+
+Sat Aug 6 19:46:37 1994 Rohan Lenard <rjl@easams.com.au>
+
+ * call.c (build_scoped_method_call): Fix error message when
+ destructor call refers to a nonexistent type.
+
+Sat Apr 16 22:43:30 1993 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * lex.h (rid): Deleted RID_RAISES, it's never used.
+ Moved RID_PUBLIC, RID_PRIVATE, RID_PROTECTED, RID_EXCEPTION,
+ RID_TEMPLATE and RID_SIGNATURE to the end of the enumeration,
+ they don't need to be touched in `grokdeclarator.'
+ (RID_LAST_MODIFIER): Defined macro to be RID_MUTABLE.
+
+ * decl.c (grokdeclarator): Use RID_LAST_MODIFIER instead of
+ RID_MAX as loop limit for finding declaration specifiers.
+
+Sat Apr 3 21:59:07 1993 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * lex.c (debug_yytranslate): Moved to parse.y since it needs to
+ access `yytname,' which is static in parse.c.
+
+Fri Apr 2 23:36:57 1993 Gerald Baumgarnter <gb@cs.purdue.edu>
+
+ * cp-tree.h (GNU_xref_ref): Fixed typo in extern declaration, it
+ was `GNU_xref_def' instead of `GNU_xref_ref.'
+
+Fri Aug 5 14:20:16 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (do_function_instantiation): Don't set TREE_PUBLIC and
+ DECL_EXTERNAL on 'extern' instantiations; wait until EOF to do that.
+ (do_type_instantiation): Likewise.
+
+ * decl2.c (import_export_inline): Decides at EOF what an inline's
+ linkage should be.
+ (finish_file): Call it.
+
+ * decl.c (start_function): Don't rely on the settings of TREE_PUBLIC
+ and DECL_EXTERNAL from do_*_instantiation. Only set
+ DECL_DEFER_OUTPUT on inlines whose linkage might actually change.
+ (finish_function): Use DECL_DEFER_OUTPUT to decide which inlines to
+ mark for later consideration, rather than DECL_FUNCTION_MEMBER_P.
+
+Fri Aug 5 01:12:20 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (get_class_offset_1, get_class_offset): New routine to
+ find the offset of the class where a virtual function is defined,
+ from the complete type.
+ * class.c (modify_one_vtable, fixup_vtable_deltas): Use
+ get_class_offset instead of virtual_offset as get_class_offset will
+ always provide the right answer.
+ * tree.c (virtual_offset): Remove. It only ever worked some of the
+ time.
+
+Tue Aug 2 12:44:21 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Put back unary_complex_lvalue call
+ that I thought was redundant.
+
+ * typeck.c (c_expand_return): Fix a case I missed before.
+
+Sun Jul 31 17:54:02 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (unify): Strip cv-quals from template type arguments (when
+ 'const T*' is matched to 'const char*', that does not mean that T is
+ 'const char').
+
+Fri Jul 29 01:03:06 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (do_type_instantiation): Instantiate nested TAGS, not
+ typedefs. Third time's the charm?
+
+ * parse.y (template_parm): Support default template parms.
+ * pt.c (process_template_parm): Likewise.
+ (end_template_parm_list): Likewise.
+ (coerce_template_parms): Likewise.
+ (mangle_class_name_for_template): Likewise.
+ (push_template_decls): Likewise.
+ (unify): Likewise.
+ * method.c (build_overload_identifier): Likewise.
+ * error.c (dump_decl): Likewise.
+
+Wed Jul 27 17:47:00 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (do_type_instantiation): Only instantiate nested *classes*.
+
+Tue Jul 26 13:22:40 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * search.c (note_debug_info_needed): Also emit debugging information
+ for the types of fields.
+
+Mon Jul 25 00:34:44 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (lookup_template_class): Pass 'template' to
+ coerce_template_parms instead of 'in_decl', since it's a more
+ meaningful context.
+
+ * typeck.c (c_expand_return): Make sure any cleanups for the return
+ expression get run.
+ (build_c_cast): Use CONVERT_EXPR for conversion to void.
+
+ * pt.c (do_type_instantiation): Also instantiate nested types.
+
+ * typeck.c (convert_for_assignment): Don't die when comparing
+ pointers with different levels of indirection.
+
+ * decl.c (grokdeclarator): The sub-call to grokdeclarator for
+ class-local typedefs sets DECL_ARGUMENTS, so we need to clear it
+ out.
+
+ * decl2.c (finish_anon_union): Don't die if the union has no
+ members.
+
+ * decl.c (grokdeclarator): Undo changes to declspecs when we're done
+ so that 'typedef int foo, bar;' will work.
+
+ * decl2.c (finish_file): Don't call expand_aggr_init for
+ non-aggregates.
+
+Mon Jul 25 00:03:10 1994 Teemu Torma <tot@trema.fi>
+
+ * decl.c (finish_function): We can't inline constructors and
+ destructors under some conditions with -fpic, but don't unset
+ DECL_INLINE.
+
+Mon Jul 25 00:03:10 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_object_ref): Make sure 'datum' is a valid object.
+
+Sun Jul 24 14:19:31 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Don't set DECL_FIELD_BITPOS on
+ non-fields.
+ (finish_struct_methods): Use copy_assignment_arg_p.
+
+ * cvt.c (cp_convert): If expr is an OFFSET_REF, resolve it instead
+ of giving an error.
+
+ * typeck.c (build_binary_op_nodefault): Don't set result_type if we
+ don't know how to compare the operands.
+
+ * decl.c (grokdeclarator): Avoid seg fault when someone uses '__op'
+ as a declarator-id in their program. Like the Linux headers do.
+ Arrgh.
+
+ * tree.c (lvalue_p): Treat calls to functions returning objects by
+ value as lvalues again.
+
+ * typeck.c (build_component_addr): Use convert_force to convert the
+ pointer in case the component type is also a private base class.
+
+ * search.c (get_matching_virtual): Fix bogus warning of overloaded
+ virtual.
+
+ * pt.c (overload_template_name): Set DECL_ARTIFICIAL on the created
+ TYPE_DECL to fix bogus shadowing warnings.
+
+Fri Jul 22 01:15:32 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (expand_aggr_init_1): const and volatile mismatches do not
+ prevent a TARGET_EXPR from initializing an object directly.
+
+Tue Jul 19 17:55:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (build_up_reference): Allow building up references to
+ `this', don't warn about making references to artificial variables
+ (like `this').
+
+ * tree.c (lvalue_p): `this' is not an lvalue.
+
+ * call.c (build_method_call): Accept using a typedef name (or
+ template type parameter) for explicit destructor calls.
+
+Thu Jul 14 09:42:23 1994 Mike Stump <mrs@cygnus.com>
+
+ * Version 2.6.0 released.
+
+Wed Jul 13 03:57:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * method.c (hack_identifier): Put back old code so lists of
+ non-functions will be handled properly.
+
+ * cp-tree.h (TYPE_NEEDS_CONSTRUCTING): #if 0 out; this macro is now
+ defined in the language-independent tree.h.
+
+ * tree.c (count_functions): Avoid bogus warning when compiling this
+ function.
+
+Mon Jul 11 18:37:20 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grok_reference_init): Always save the initializer of a
+ reference.
+
+Fri Jul 8 17:41:46 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (cplus_expand_expr_stmt): Wrap statement expressions inside
+ CLEANUP_POINT_EXPRs so that the stack slots can be reused.
+ (disabled for now)
+
+Fri Jul 8 12:59:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * method.c (hack_identifier): Fix for new overloading.
+
+ * typeck.c (build_binary_op_nodefault): Don't mess with division by
+ zero.
+
+Fri Jul 8 13:20:28 1994 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * decl2.c (finish_file): Only call walk_sigtables, if
+ flag_handle_signatures is turned on, don't waste time otherwise.
+
+Fri Jul 8 02:27:41 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (push_overloaded_decl): Don't create overloads of one when
+ shadowing a class type.
+ * typeck.c (build_x_function_call): Complain about overloads of one.
+
+ * decl.c (grokdeclarator): Don't try to treat a char* as a tree.
+ (grokdeclarator): Fix setting of TREE_STATIC.
+ (start_decl): Clear DECL_IN_AGGR_P after calling duplicate_decls.
+
+Thu Jul 7 22:20:46 1994 Gerald Baumgartner <gb@andros.cygnus.com>
+
+ * cp-tree.h (walk_sigtables): Created extern declaration.
+ * decl2.c (walk_sigtables): Created function, patterned after
+ walk_vtables, even though we only need it to write out sigtables.
+ (finish_sigtable_vardecl): Created function.
+ (finish_vtable_vardecl): Changed 0 to NULL_PTR.
+ (finish_file): Call walk_sigtables.
+
+ * sig.c (build_signature_table_constructor): Mark class member
+ function pointed to from signature table entry as addressable.
+
+Thu Jul 7 13:39:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (start_decl): Check new decl of static member variable
+ against the declaration in the class here.
+ (grokvardecl): Instead of here.
+
+ * class.c (prepare_fresh_vtable): Call import_export_vtable if not
+ -fvtable-thunks.
+ (build_vtable): Likewise.
+
+ * decl2.c (import_export_vtable): Move logic for deciding the
+ interface of a template class from here.
+ (import_export_template): To here.
+ (finish_vtable_vardecl): Call import_export_template before
+ import_export_vtable.
+
+Wed Jul 6 20:25:48 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (init_exception_processing): Setup interim_eh_hook to
+ call lang_interim_eh.
+ * except.c (do_unwind): Propagate throw object value across
+ stack unwinding.
+ * except.c (saved_throw_value): Used to hold the value of the object
+ being thrown. It is always a reference to the real value.
+ * except.c (expand_start_catch_block): Add handling for the
+ value of the exception object.
+ * except.c (expand_start_catch_block): Add handler for the handler,
+ so that throws inside the handler go to the outer block.
+ * except.c (expand_end_catch_block): Likewise.
+ * parse.y (handler_args): Use parm instead, as the other doesn't yet
+ handle references correctly.
+
+Wed Jul 6 17:55:32 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl2.c (mark_vtable_entries): If -ftable-thunks, set the
+ vtable entry properly to abort.
+
+Tue Jul 5 14:07:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Downgrade division by zero
+ errors to warnings.
+
+ * call.c (build_overload_call_real): Handle fnname being a list of
+ functions.
+ * typeck.c (build_x_function_call): Pass list of functions to
+ build_overload_call, not just the name.
+ * tree.c (count_functions): Complain when called for invalid
+ argument.
+
+ * decl.c (grokdeclarator): Fix settings of TREE_STATIC, TREE_PUBLIC
+ and DECL_EXTERNAL on static members and initialized const members.
+ * decl2.c (grokfield): Reflect this change.
+
+Fri Jul 1 09:35:51 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (init): ANSI C++ does not forbid { }.
+
+Thu Jun 30 00:35:22 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (lang_decode_option): Set warn_nonvdtor along with -Wall.
+ warn_nonvdtor defaults to off.
+
+ * class.c (instantiate_type): Use comptypes rather than relying on
+ types to satisfy ==.
+
+ * decl.c (start_function): Set DECL_DEFER_OUTPUT on all inlines that
+ might be static.
+
+ * tree.c (build_cplus_new): Never build WITH_CLEANUP_EXPRs.
+
+ * decl.c (grok_reference_init): Deal with ADDR_EXPRs of TARGET_EXPRs.
+
+ * cvt.c (cp_convert): Pass 0 to with_cleanup_p arg of
+ build_cplus_new.
+
+Wed Jun 29 22:31:09 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (finish_file): Maybe consider static inlines multiple
+ times, in case they reference each other.
+
+Tue Jun 28 11:58:38 1994 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * class.c (finish_struct): Don't `cons_up_default_function's
+ for signatures.
+ (finish_struct): Handle an empty method_vec correctly.
+
+ * decl.c (grokdeclarator): Don't warn about a signature being
+ empty in a signature pointer declaration if we only saw a
+ forward declaration of the signature. Changed `warning's into
+ `cp_warning's.
+
+ * sig.c (build_sigtable): Don't die if a null signature table
+ constructor is returned.
+ (build_signature_pointer_constructor): If the signature table
+ constructor is null, the _sptr field is set to a null pointer
+ and cast to the appropriate type. Make copies of all null
+ pointers so that the type null_pointer_node doesn't get changed.
+ (build_signature_table_constructor): Added comments.
+
+ * sig.c (build_signature_pointer_constructor): Complain if we
+ try to assign to/initialize a signature pointer/reference of
+ an undefined signature.
+
+Mon Jun 27 14:05:16 1994 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * typeck2.c (store_init_value): Don't be pedantic about
+ non-constant initializers of signature tables/pointers/references.
+
+Fri Jun 24 16:49:41 1994 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * decl.c (grokdeclarator): If we are grokking an opaque typedef
+ in a signature, don't complain about it begin static.
+
+Wed Jun 29 16:44:45 1994 Mike Stump <mrs@cygnus.com>
+
+ Fixes a problem of the this pointer being wrong in virtual calls to
+ methods that are not overridden in more derived classes.
+
+ * class.c (fixup_vtable_delta): New routine. It will fixup the
+ delta entries in vtables, wheever they need updating.
+ * class.c (finish_struct): Call the new routine for all virtual
+ bases, as they can have different offsets, than those used in base
+ classes that we derive our vtable from.
+
+Tue Jun 28 23:49:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_binary_op): Use the types before default
+ conversions in the error message.
+
+ * *.c: Use c_build_type_variant instead of build_type_variant where
+ the type might be an array.
+
+ * call.c (build_method_call): Call build_type_variant and
+ build_reference_type in the right order.
+ * decl.c (record_builtin_type): Likewise.
+
+Wed Jun 29 16:58:53 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Call build_type_variant and
+ build_reference_type in the right order.
+ * decl.c (record_builtin_type): Likewise.
+
+Tue Jun 28 23:49:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_binary_op): Use the types before default
+ conversions in the error message.
+
+ * *.c: Use c_build_type_variant instead of build_type_variant where
+ the type might be an array.
+
+Sat Jun 25 11:50:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): Try UDC's before doing the
+ reinterpret_cast thang, though.
+
+Fri Jun 24 01:24:01 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (c_expand_return): Don't USE the return value location
+ after we've expanded the jump.
+
+ * decl2.c (finish_file): Make sure DECL_SAVED_INSNS is not 0 before
+ trying to write out an inline.
+
+ * cvt.c (build_up_reference): Also do address adjustment when the
+ target type uses MI.
+ (convert_to_reference): Try UDCs only after built-in conversions.
+ (build_type_conversion_1): Don't play games with the argument to the
+ method.
+ (build_type_conversion): #if 0 out code for binding to reference.
+
+Thu Jun 23 00:22:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (finish_file): Use TREE_SYMBOL_REFERENCED to decide
+ whether to emit inlines.
+
+ * decl.c (grokdeclarator): Set explicit_int for decls that just
+ specify, say, 'long'.
+
+ * init.c (do_friend): Do overload C functions (or call pushdecl,
+ anyaway).
+
+Wed Jun 22 13:40:49 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (build_up_reference): Don't call readonly_error.
+ (convert_to_reference): Propagate const and volatile from expr to
+ its type.
+
+ * tree.c (lvalue_p): Random CALL_EXPRs are not lvalues.
+
+ * cvt.c (build_up_reference): Break out WITH_CLEANUP_EXPR when
+ creating a temporary.
+ (convert_to_reference): Lose excessive and incorrect trickiness.
+ (cp_convert): Call build_cplus_new with with_cleanup_p set.
+
+ * typeck2.c (build_functional_cast): Likewise.
+
+Tue Jun 21 17:38:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): signed, unsigned, long and short all
+ imply 'int'.
+
+ * decl.c (grokdeclarator): Allow "this is a type" syntax.
+ (grok_reference_init): Simplify and fix.
+
+Sun Jun 19 17:08:48 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): pedwarn about a typedef that specifies no
+ type.
+
+Sat Jun 18 04:16:50 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (start_function): Move TREE_PUBLIC and DECL_EXTERNAL
+ tinkering to after call to pushdecl.
+
+Fri Jun 17 14:48:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Handle destructors for non-aggregate
+ types properly.
+
+Thu Jun 16 16:48:05 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Make sure that the name given for the
+ destructor matches the constructor_name of the instance.
+
+ * pt.c (do_function_instantiation): A non-extern instantiation
+ overrides a later extern one.
+ (do_type_instantiation): Likewise.
+
+Wed Jun 15 19:34:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (expand_aggr_init): Use TYPE_MAIN_VARIANT to get the
+ unqualified array type.
+
+ * cp-tree.h (EMPTY_CONSTRUCTOR_P): Tests whether NODE is a
+ CONSTRUCTOR with no elements.
+
+ * decl.c (various): Lose empty_init_node.
+ (finish_decl): Use EMPTY_CONSTRUCTOR_P, do the empty CONSTRUCTOR
+ thing depending on the value of DECL_COMMON instead of
+ flag_conserve_space, do the empty CONSTRUCTOR thing for types that
+ don't have constructors, don't treat a real empty CONSTRUCTOR
+ specially.
+
+ * typeck2.c (process_init_constructor): Don't treat empty_init_node
+ specially.
+
+Wed Jun 15 19:05:25 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (override_one_vtable): Don't forget to merge in an old
+ overrider when we wanted to reuse a vtable, but couldn't.
+
+Wed Jun 15 15:03:16 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (start_decl): Put statics in common again.
+
+ * decl.c (grokdeclarator): Return NULL_TREE for an error rather than
+ setting the type to error_mark_node.
+
+ * typeck.c (build_modify_expr): Build up a COMPOUND_EXPR for enum
+ bitfield assignments.
+
+Tue Jun 14 12:23:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grok_op_properties): Const objects can be passed by value.
+
+Mon Jun 13 03:10:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (import_export_vtable): Force implicit instantiations to
+ be interface_only when -fno-implicit-templates.
+
+ * decl.c (duplicate_decls): Redeclaring a class template name is an
+ error.
+
+ * pt.c (end_template_decl): Call GNU_xref_decl for class templates.
+ * xref.c (GNU_xref_decl): Support templates.
+
+Sat Jun 11 17:09:05 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grok_op_properties): Split out checking for whether this
+ function should suppress the default assignment operator.
+ * decl2.c (grok_function_init): Likewise.
+ (copy_assignment_arg_p): New function do do just that.
+ Now considers virtual assignment operators that take a base as an
+ argument to count as copy assignment operators.
+
+ * search.c (dfs_debug_mark): Lose checks for DWARF_DEBUG and
+ TREE_ASM_WRITTEN, as they are redundant.
+
+ * pt.c (end_template_decl): Don't try to set DECL_CLASS_CONTEXT on a
+ decl that has no LANG_SPECIFIC part.
+ (do_type_instantiation): Force the debugging information for this
+ type to be emitted.
+
+ * decl.c (start_decl): Clear up uses of various types of templates
+ (say sorry for static data members, rather than "invalid template").
+ (expand_static_init): Fix initialization of static data members of
+ template classes.
+
+Fri Jun 10 00:41:19 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Set DECL_CONTEXT on static data members.
+
+ * g++.c (main): Use -xc++-cpp-output for .i files.
+
+ * pt.c (tsubst): Give meaningful error about declaring template for
+ a copy constructor which was not declared in the class template.
+ (do_type_instantiation): Explicit instantiation before the class
+ template is an error.
+ (instantiate_template): Don't die if tsubst returns error_mark_node.
+
+Thu Jun 9 19:04:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Don't synthesize the copy assignment operator if the one in a base
+ class is pure virtual.
+ * cp-tree.h (TYPE_HAS_ABSTRACT_ASSIGN_REF): New macro to indicate
+ whether the type has a pure virtual copy assignment operator.
+ * class.c (finish_base_struct): Don't generate the copy assignment
+ operator if a base class has a pure virtual one.
+ * decl.c (grok_op_properties): Add disabled code to set
+ TYPE_HAS_ABSTRACT_ASSIGN_REF with comment pointing to where it is
+ actually set.
+ * decl2.c (grok_function_init): Set TYPE_HAS_ABSTRACT_ASSIGN_REF.
+
+ * decl2.c (import_export_vtable): Always treat template
+ instantiations as if write_virtuals >= 2, and treat implicit
+ instantiations as external if -fno-implicit-templates.
+ (finish_file): Output all pending inlines if
+ flag_keep_inline_functions.
+
+Wed Jun 8 20:48:02 1994 Mike Stump <mrs@cygnus.com>
+
+ * tree.c (layout_vbasetypes): Align virtual base classes inside
+ complete objects, so that we don't core dump on machines such as
+ SPARCs when we access members that require larger than normal
+ alignments, such as a double. Also, we bump up the total alignment
+ on the complete type, as necessary.
+
+Wed Jun 8 16:18:14 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * gxxint.texi (Free Store): New section with code for examining
+ cookie.
+ (Limitations of g++): Remove operator delete entry, since it is no
+ longer accurate. Fix access control entry.
+
+ * typeck.c (build_unary_op): Pedwarn about taking the address of or
+ incrementing a cast to non-reference type.
+ (build_modify_expr): Use convert instead of convert_force again.
+
+ * search.c (get_base_distance): Use IS_AGGR_TYPE_CODE to check for
+ class type, not == RECORD_TYPE.
+
+ * decl.c (grokdeclarator): Cope with grokfndecl returning NULL_TREE.
+
+ * typeck2.c (report_case_error): #if 0 out.
+ * lex.c (real_yylex): Lose RANGE.
+ * parse.y: Likewise.
+
+Tue Jun 7 18:17:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (simple_stmt, case ranges): Use ELLIPSIS instead of RANGE.
+
+Mon Jun 6 19:39:57 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_c_cast): Don't shortcut conversions to the same
+ type. Don't replace consts with their values here, since that's now
+ done in cp_convert.
+
+ * cvt.c (cp_convert): When converting to bool, take
+ integer_zero_node to false_node and all other INTEGER_CSTs to
+ true_node.
+ (build_type_conversion): Don't complain about multiple conversions
+ to float if we're not really converting.
+
+Fri Jun 3 02:10:56 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Implement 'extern template class A<int>;' syntax for suppressing
+ specific implicit instantiations.
+ * cp-tree.h: Update prototypes for do_*_instantiation.
+ * pt.c (do_pending_expansions): Don't compile 'extern' explicit
+ instantiations.
+ (do_function_instantiation): Set DECL_EXTERNAL on 'extern' explicit
+ instantiations.
+ (do_type_instantiation): Likewise.
+ * parse.y (explicit_instantiation): Support 'extern template class
+ A<int>;' syntax.
+ * decl.c (start_function): Don't modify the settings of TREE_PUBLIC
+ and DECL_EXTERNAL on explicit instantiations.
+
+ * cvt.c (cp_convert): Replace constants with their values before
+ converting.
+ (cp_convert): Consistently use 'e' instead of 'expr'.
+
+Thu Jun 2 03:53:30 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck2.c (build_x_arrow): Resolve OFFSET_REFs first.
+
+Wed Jun 1 18:57:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck2.c (digest_init): Handle initializing a pmf with an
+ overloaded method.
+ * typeck.c (build_ptrmemfunc): Handle overloaded methods.
+
+ * decl.c (pushtag): Use build_decl to make TYPE_DECLs.
+ (xref_defn_tag): Likewise.
+ * pt.c (process_template_parm): Likewise.
+ (lookup_template_class): Likewise.
+ (push_template_decls): Likewise.
+ (instantiate_class_template): Likewise.
+ (create_nested_upt): Likewise.
+ * class.c (finish_struct): Don't try to set DECL_CLASS_CONTEXT on
+ TYPE_DECLs.
+
+ * typeck.c (convert_arguments): Make sure type is not NULL before
+ checking its TREE_CODE.
+
+Wed Jun 1 17:40:39 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (get_derived_offset): New routine.
+ * class.c (finish_base_struct): Make sure we set BINFO_VTABLE and
+ BINFO_VIRTUALS when we choose a new base class to inherit from.
+ * class.c (modify_one_vtable): Use get_derived_offset to get the
+ offset to the most base class subobject that we derived this binfo
+ from.
+ * class.c (finish_struct): Move code to calculate the
+ DECL_FIELD_BITPOS of the vfield up, as we need might need it for
+ new calls to get_derived_offset in modify_one_vtable.
+
+Wed Jun 1 16:50:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (build_member_call): Use build_pointer_type instead of
+ TYPE_POINTER_TO.
+
+Wed Jun 1 11:11:15 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Make sure we have a DNAME set before we
+ try to use it in an error.
+
+Wed Jun 1 09:48:49 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (convert_arguments, convert_for_initialization): Don't
+ strip NOP_EXPRs, when we are converting to a reference.
+
+Wed Jun 1 01:11:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_modify_expr): Don't dereference references when
+ initializing them.
+
+ * decl2.c (grokfield): Don't check for grokdeclarator returning
+ error_mark_node any more.
+
+ * decl.c (grokfndecl): Return NULL_TREE instead of error_mark_node.
+ (start_method): Return void_type_node instead of error_mark_node.
+
+ * typeck.c (build_modify_expr): Resolve offset refs earlier.
+
+Tue May 31 16:06:58 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Resolve OFFSET_REFs in the object.
+
+ * typeck.c (build_modify_expr): Dereference references before trying
+ to assign to them.
+
+ * call.c (build_method_call): Don't confuse type conversion
+ operators with constructors.
+ * typeck2.c (build_functional_cast): Just call build_c_cast if there
+ was only one parameter.
+ * method.c (build_typename_overload): Don't set
+ IDENTIFIER_GLOBAL_VALUE on these identifiers.
+ * decl.c (grok_op_properties): Warn about defining a type conversion
+ operator that converts to a base class (or reference to it).
+ * cvt.c (cp_convert): Don't try to use a type conversion operator
+ when converting to a base class.
+ (build_type_conversion_1): Don't call constructor_name_full on an
+ identifier.
+ * cp-tree.h (DERIVED_FROM_P): Should be self-explanatory.
+
+ * decl.c (start_decl): Don't complain that error_mark_node is an
+ incomplete type.
+ (finish_decl): Check for type == error_mark_node.
+
+Mon May 30 23:38:55 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (start_function): Set DECL_DEFER_OUTPUT on implicit
+ instantiations and inline members.
+
+ * spew.c (yylex): Set looking_for_template if the next token is a '<'.
+
+ * lex.h: Declare looking_for_template.
+
+ * decl.c (lookup_name_real): Use looking_for_template to arbitrate
+ between type and template interpretations of an identifier.
+
+Sat May 28 04:07:40 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (instantiate_template): Zero out p if we found a
+ specialization.
+
+ * decl.c (grokdeclarator): Elucidate warning.
+ (grokdeclarator): If pedantic AND -ansi, complain about long long.
+
+ Make explicit instantiation work reasonably. It is now appropriate
+ to deprecate the use of -fexternal-templates.
+ * pt.c (instantiate_template): Set DECL_TEMPLATE_SPECIALIZATION or
+ DECL_IMPLICIT_INSTANTIATION on fndecl as appropriate.
+ (end_template_instantiation): Reflect changes in USE_TEMPLATE
+ semantics.
+ (do_pending_expansions): if (!flag_implicit_templates) DECIDE(0);
+ (do_function_instantiation): Don't set EXPLICIT_INST if
+ flag_external_templates is set. Do set TREE_PUBLIC and DECL_EXTERN
+ appropriately otherwise.
+ (do_type_instantiation): Set interface info for class. Set
+ TREE_PUBLIC and DECL_EXTERN for methods. Do none of this if
+ flag_external_templates is set.
+ * parse.y: Reflect changes in USE_TEMPLATE semantics.
+ * decl2.c: New flag flag_implicit_templates determines whether or
+ not implicit instantiations get emitted. This flag currently
+ defaults to true, and must be true for -fexternal-templates to work.
+ (finish_file): Consider flag_implement_inlines when
+ setting DECL_EXTERNAL. Consider flag_implicit_templates when
+ deciding whether or not to emit a static copy.
+ * decl.c (start_function): Set TREE_PUBLIC and DECL_EXTERNAL
+ properly for template instantiations.
+ (start_method): Set DECL_IMPLICIT_INSTANTIATION on methods of a
+ template class.
+ * cp-tree.h (CLASSTYPE_USE_TEMPLATE): Change semantics.
+ (DECL_USE_TEMPLATE): Parallel macro for FUNCTION and VAR_DECLs.
+ (various others): Accessor macros for the above.
+
+Fri May 27 13:57:40 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Division by constant zero is
+ an error.
+
+Fri May 27 13:50:15 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (override_one_vtable): Don't modify things we don't own.
+
+Fri May 27 01:42:58 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (finish_decl): Don't postpone processing the initializer of
+ a decl with DECL_EXTERNAL set, and do call rest_of_compilation for a
+ PUBLIC const at toplevel.
+ (grokdeclarator): pedwarn about initializing non-const or
+ non-integral statics in the class body.
+
+ * decl.c (pushtag): Don't try to set DECL_CLASS_CONTEXT on a
+ TYPE_DECL.
+
+ * call.c (convert_harshness): Dereference reference on rhs before
+ proceeding, properly grok passing const things to non-const
+ references.
+
+ * typeck.c (build_unary_op): Soften error about taking the address
+ of main() to a pedwarn.
+
+ * lex.c (default_copy_constructor_body): Unambiguously specify base
+ classes (i.e. A((const class ::A&)_ctor_arg) ).
+ (default_assign_ref_body): Likewise.
+
+Thu May 26 13:13:55 1994 Gerald Baumgartner <gb@mexican.cygnus.com>
+
+ * decl2.c (grokfield): Don't complain about local signature
+ method declaration without definition.
+
+ * call.c (convert_harshness): If `type' is a signature pointer
+ and `parmtype' is a pointer to a signature, just return 0. We
+ don't really convert in this case; it's a result of making the
+ `this' parameter of a signature method a signature pointer.
+
+ * call.c (build_method_call): Distinguish calling the default copy
+ constructor of a signature pointer/reference from a signature
+ member function call.
+
+Thu May 26 12:56:25 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (grokfield): Don't set TREE_PUBLIC on member function
+ declarations.
+
+ * decl.c (duplicate_decls): A previous function declaration as
+ static overrides a subsequent non-static definition.
+ (grokdeclarator): Don't set TREE_PUBLIC on inline method
+ declarations.
+
+Wed May 25 14:36:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Handle initialization of static const
+ members.
+ (finish_decl): Likewise.
+
+ * decl2.c (grokfield): Allow initialization of static const members
+ even when pedantic.
+
+ * decl2.c (grokfield): Deal with grokdeclarator returning
+ error_mark_node.
+
+ * decl.c (grok_ctor_properties): Return 0 for A(A) constructor.
+ (grokfndecl): Check the return value of grok_ctor_properties.
+ (start_method): Likewise.
+
+ * parse.y (absdcl): Expand type_quals inline.
+
+Tue May 24 19:10:32 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (pushtag): Use IS_AGGR_TYPE rather than checking for a
+ RECORD_TYPE.
+
+Tue May 24 18:09:16 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * cp-tree.h (VTABLE_NAME_FORMAT): If flag_vtable_thunks,
+ always use "__vt_%s".
+ * decl2.c (finish_vtable_vardecl): Don't consider abstract virtuals
+ when looking for a "sentinal" method (to decide on emitting vtables).
+ * decl2.c (finish_file): Scan all decls for thunks that need
+ to be emitted.
+ * decl2.c (finish_vtable_vardecl): Don't bother calling emit_thunk.
+ * method.c (make_thunk): Use a more meaningful label. If there
+ exists a matching top-level THUNK_DECL re-use it; otherwise
+ create a new THUNK_DECL (and declare it).
+ * method.c (emit_thunk): Make thunk external/public depending
+ on the underlying method.
+
+Tue May 24 00:22:04 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (tsubst): Use lookup_name_nonclass to find guiding decls, not
+ lookup_name.
+
+ * call.c (build_overload_call_real): Don't immediately pick a
+ function which matches perfectly.
+
+ * decl.c (grokdeclarator): Use c_build_type_variant for arrays.
+ (grokdeclarator): Warn about, and throw away, cv-quals attached to a
+ reference (like 'int &const j').
+
+ * typeck.c (convert_arguments): Don't mess with i for methods.
+ * call.c (build_method_call): Pass the function decl to
+ convert_arguments.
+
+ * typeck.c (comp_ptr_ttypes_real): New function. Implements the
+ checking for which multi-level pointer conversions are allowed.
+ (comp_target_types): Call it.
+ (convert_for_assignment): Check const parity on the ultimate target
+ type, too. And make those warnings pedwarns.
+
+Mon May 23 14:11:24 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * error.c (dump_char): Use TARGET_* for character constants.
+
+Mon May 23 13:03:03 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * tree.c (debug_no_list_hash): Make static.
+
+ * decl.c (decls_match): Say the types don't match if newdecl ends up
+ with a null type, after we've checked if olddecl does.
+ (pushdecl): Check if the decls themselves match before looking for
+ an extern redeclared as static, to avoid inappropriate and incorrect
+ warnings.
+
+Fri May 20 14:04:34 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Make warning about duplicate short, etc.
+ a pedwarn.
+
+ * typeck.c (build_c_cast): Casting to function or method type is an
+ error.
+
+ * class.c (finish_struct): Make warning for anonymous class with no
+ instances a pedwarn.
+
+ * Makefile.in (stamp-parse): Expect a s/r conflict.
+
+ * typeck.c (build_modify_expr): pedwarn about using a non-lvalue
+ cast as an lvalue.
+
+Thu May 19 12:08:48 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (type_promotes_to): Make sure bool promotes to int rather
+ than unsigned on platforms where sizeof(char)==sizeof(int).
+
+Wed May 18 14:27:06 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_c_cast): Tack on a NOP_EXPR when casting to
+ another variant.
+ (build_modify_expr): Don't strip NOP_EXPRs, and don't get tricky
+ and treat them as lvalues.
+
+ * decl.c (shadow_tag): Do complain about forward declarations of
+ enums and empty declarations.
+ * parse.y: Don't complain about forward declarations of enums and
+ empty declarations.
+
+ * typeck.c (convert_for_assignment): Complain about changing
+ the signedness of a pointer's target type.
+
+ * parse.y (stmt): Move duplicated code for checking case values from
+ here.
+ * decl2.c (check_cp_case_value): To here. And add a call to
+ constant_expression_warning.
+
+ * typeck.c (convert_for_assignment): Don't complain about assigning
+ a negative value to bool.
+
+ * decl.c (init_decl_processing): Make bool unsigned.
+
+ * class.c (finish_struct): Allow bool bitfields.
+
+Wed May 18 12:35:27 1994 Ian Lance Taylor <ian@tweedledumb.cygnus.com>
+
+ * Make-lang.in (c++.install-man): Get g++.1 from $(srcdir)/cp.
+
+Wed May 18 03:28:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (build_type_conversion): Lose special handling of
+ truthvalues.
+
+ * search.c (dfs_pushdecls): Improve shadowing warning.
+
+Tue May 17 13:34:46 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (build_delete): Throw away const and volatile on `this'.
+
+ * decl.c (finish_enum): Put the constants in TYPE_VALUES again,
+ rather than the enumerators.
+ (pushtag): s/cdecl/c_decl/g
+
+Mon May 16 23:04:01 1994 Stephen R. van den Berg <berg@pool.informatik.rwth-aachen.de>
+
+ * cp/typeck.c (common_type): Attribute merging.
+ (comp_types): Utilise COMP_TYPE_ATTRIBUTES macro.
+
+ * cp/parse.y: Revamp attribute parsing.
+
+Mon May 16 01:40:34 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (shadow_tag): Also check for inappropriate use of auto and
+ register.
+
+ * method.c (build_overload_name): Clarify that the illegal case is a
+ pointer or reference to array of unknown bound.
+
+ * error.c (dump_type_prefix): Print references to arrays properly.
+
+ * typeck.c (various): Be more helpful in pointer
+ comparison diagnostics.
+
+ * tree.c (lvalue_p): MODIFY_EXPRs are lvalues again. Isn't this
+ fun?
+
+ * parse.y: Also catch an error after valid stmts.
+
+ * search.c (dfs_init_vbase_pointers): Don't abort because `this' is
+ const.
+
+ * typeck.c (convert_for_initialization): If call to
+ convert_to_reference generated a diagnostic, print out the parm
+ number and function decl if any.
+
+ * errfn.c (cp_thing): Check atarg1 to determine whether or not we're
+ specifying a line, not atarg.
+
+ * tree.c (build_cplus_method_type): Always make `this' const.
+
+ * decl2.c (grokclassfn): If -fthis-is-variable and this function is
+ a constructor or destructor, make `this' non-const.
+
+ * typeck.c (build_modify_expr): Don't warn specially about
+ assignment to `this' here anymore, since it will be caught by the
+ usual machinery.
+
+ * various: Disallow specific GNU extensions (variable-size arrays,
+ etc.) when flag_ansi is set, not necessarily when pedantic is set,
+ so that people can compile with -pedantic-errors for tighter const
+ checking and such without losing desirable extensions.
+
+ * typeck2.c (build_functional_cast): Call build_method_call with
+ LOOKUP_PROTECT.
+ (process_init_constructor): Only process FIELD_DECLs.
+
+ * decl.c (finish_decl): Also force static consts with no explicit
+ initializer that need constructing into the data segment.
+
+ * init.c (build_delete): Undo last patch, as it interferes with
+ automatic cleanups.
+
+Sat May 14 01:59:31 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c, class.h, cp-tree.h, cvt.c, decl2.c: Lose old overloading
+ code.
+
+ * init.c (build_delete): pedwarn about using plain delete to delete
+ an array.
+
+Fri May 13 16:45:07 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (comp_target_types): Be more helpful in contravariance
+ warnings, and make them pedwarns.
+
+ * decl.c (grokdeclarator): Use decl_context to decide whether or not
+ this is an access declaration.
+
+ * class.c (finish_struct_bits): Set TYPE_HAS_INT_CONVERSION if it
+ has a conversion to enum or bool, too.
+
+Fri May 13 16:31:27 1994 Mike Stump <mrs@cygnus.com>
+
+ * method.c (emit_thunk): Make declaration for
+ current_call_is_indirect local (needed for hppa).
+
+Fri May 13 16:16:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (uses_template_parms): Grok BOOLEAN_TYPE.
+ (tsubst): Likewise.
+
+Fri May 13 16:23:32 1994 Mike Stump <mrs@cygnus.com>
+
+ * pt.c (tsubst): If there is already a function for this expansion,
+ use it.
+ * pt.c (instantiate_template): Likewise.
+
+Fri May 13 10:30:42 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (implicitly_scoped_stmt, simple_stmt case): Use
+ kept_level_p for MARK_ENDS argument to expand_end_bindings, to avoid
+ generating debug info for unemitted symbols on some systems.
+
+ * cp-tree.h (build_static_cast, build_reinterpret_cast,
+ build_const_cast): Add declarations.
+
+Fri May 13 09:50:31 1994 Mike Stump <mrs@cygnus.com>
+
+ * search.c (expand_indirect_vtbls_init): Fix breakage from Apr 27
+ fix. We now try get_binfo, and if that doesn't find what we want,
+ we go back to the old method, which still sometimes fails.
+
+Fri May 13 01:43:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (initdcl): Call cplus_decl_attributes on the right
+ variable.
+ * decl2.c (cplus_decl_attributes): Don't call decl_attributes for
+ void_type_node.
+
+ * typeck.c (build_binary_op_nodefault): Change result_type for
+ comparison ops to bool.
+ (build_binary_op): Convert args of && and || to bool.
+ * cvt.c (build_default_binary_type_conversion): Convert args of &&
+ and || to bool.
+ (build_default_unary_type_conversion): Convert arg of ! to bool.
+ (type_promotes_to): bool promotes to int.
+
+Fri May 13 01:43:18 1994 Mike Stump <mrs@cygnus.com>
+
+ Implement the new builtin `bool' type.
+ * typeck.c (build_binary_op_nodefault): Convert args of && and || to
+ bool.
+ (build_unary_op): Convert arg of ! to bool.
+ * parse.y: Know true and false. Use bool_truthvalue_conversion.
+ * method.c (build_overload_value): Know bool.
+ (build_overload_name): Likewise.
+ * lex.c (init_lex): Set up RID_BOOL.
+ * gxx.gperf: Add bool, true, false.
+ * error.c (*): Know bool.
+ * decl.c (init_decl_processing): Set up bool, true, false.
+ * cvt.c (cp_convert): Handle conversion to bool.
+ (build_type_conversion): Likewise.
+ * *.c: Accept bool where integers and enums are accepted (use
+ INTEGRAL_CODE_P macro).
+
+Thu May 12 19:13:54 1994 Richard Earnshaw <rwe11@cl.cam.ac.uk>
+
+ * g++.c: Use #ifdef for __MSDOS__, not #if.
+
+Thu May 12 18:05:18 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (lang_f_options): Handle -fshort-temps. -fshort-temps
+ gives old behavior , and destroys temporaries earlier. Default
+ behavior now conforms to the ANSI working paper.
+
+Thu May 12 14:45:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_modify_expr): Understand MODIFY_EXPR as an lvalue.
+ Use convert_force to convert the result of a recursive call when we
+ are dealing with a NOP_EXPR. Don't automatically wrap MODIFY_EXPRs
+ in COMPOUND_EXPRs any more.
+ (various): Lose pedantic_lvalue_warning.
+ (unary_complex_lvalue): Understand MODIFY_EXPR.
+
+ * cvt.c (convert_to_reference): Allow DECL to be error_mark_node if
+ we don't know what we're initializing.
+
+Wed May 11 01:59:36 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): Modify to use convtype parameter.
+ Only create temporaries when initializing a reference, not when
+ casting.
+ (cp_convert): New main function.
+ (convert): Call cp_convert.
+ * cvt.c, decl.c, typeck.c: Fix calls to convert_to_reference.
+ * cp-tree.h (CONV_*): New constants used by conversion code for
+ selecting conversions to perform.
+
+ * tree.c (lvalue_p): MODIFY_EXPRs are no longer lvalues.
+
+ * typeck.c (build_{static,reinterpret,const_cast): Stubs that just
+ call build_c_cast.
+ * parse.y: Add {static,reinterpret,const}_cast.
+ * gxx.gperf: Likewise.
+
+ * typeck.c (common_type): Allow methods with basetypes of different
+ UPTs.
+ (comptypes): Deal with UPTs.
+ (build_modify_expr): Wrap all MODIFY_EXPRs in a COMPOUND_EXPR.
+
+ * pt.c (end_template_decl): Check for multiple definitions of member
+ templates.
+
+ * call.c (build_method_call): Complain about calling an abstract
+ virtual from a constructor.
+
+ * typeck.c (pointer_int_sum): Check for the integer operand being 0
+ after checking the validity of the pointer operand.
+
+ * typeck2.c (digest_init): Pedwarn about string initializer being
+ too long.
+
+Tue May 10 12:10:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (push_overloaded_decl): Only throw away a builtin if the
+ decl in question is the artificial one.
+
+ * parse.y (simple_stmt, switch): Use implicitly_scoped_stmt because
+ expand_{start,end}_case cannot happen in the middle of a block.
+
+ * cvt.c (build_type_conversion_1): Use convert again.
+
+Tue May 10 11:52:04 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck2.c (digest_init): Make sure we check for signed and
+ unsigned chars as well when warning about string initializers.
+
+ * init.c (emit_base_init): Check if there's a DECL_NAME on the
+ member before trying to do an initialization for it.
+
+Tue May 10 11:34:37 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Don't do anything useful when cross compiling.
+
+Tue May 10 03:04:13 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (duplicate_decls): Fix up handling of builtins yet again.
+ (push_overloaded_decl): Likewise.
+
+ * cvt.c (convert): Don't look for void type conversion.
+
+Mon May 9 18:05:41 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (do_friend): Only do a pushdecl for friends, not
+ pushdecl_top_level.
+
+Mon May 9 13:36:34 1994 Jim Wilson <wilson@sphagnum.cygnus.com>
+
+ * decl.c (lookup_name_current_level): Put empty statement after
+ the label OUT to make the code valid C.
+
+Mon May 9 12:20:57 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Only complain about
+ comparing void * and a function pointer if void * is smaller.
+
+Sun May 8 01:29:13 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (lookup_name_current_level): Move through temporary binding
+ levels.
+
+ * parse.y (already_scoped_stmt): Revive.
+ (simple_stmt): Use it again.
+
+ * decl.c (poplevel): Always call poplevel recursively if we're
+ dealing with a temporary binding level.
+
+Sat May 7 10:52:28 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (finish_decl): Make sure we run cleanups for initial values
+ of decls. Cures memory leak.
+ * decl.c (expand_static_init): Likewise for static variables.
+ * decl2.c (finish_file): Likewise for globals.
+
+Sat May 7 03:57:44 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (commonparms): Don't complain about redefining default
+ args.
+
+ * decl.c (duplicate_decls): Don't complain twice about conflicting
+ function decls.
+ (decls_match): Don't look at default args.
+ (redeclaration_error_message): Complain about redefining default
+ args.
+
+ * call.c (build_overload_call_real): Also deal with guiding
+ declarations coming BEFORE the template decl.
+
+ * pt.c (unify): Allow different parms to have different
+ cv-qualifiers.
+ (unify): Allow trivial conversions on non-template parms.
+
+Fri May 6 03:53:23 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (tsubst): Support OFFSET_TYPEs.
+ (unify): Likewise.
+
+ * decl2.c (finish_decl_parsing): Call push_nested_class with a type.
+
+ * init.c (build_offset_ref): Fix error message.
+ * search.c (lookup_field): Likewise.
+
+ * call.c (build_scoped_method_call): Pass binfo to
+ build_method_call.
+ * typeck.c (build_object_ref): Likewise.
+
+ * typeck2.c (binfo_or_else): Don't return a _TYPE.
+
+ * class.c (finish_struct): Don't complain about re-use of inherited
+ names or shadowing of type decls.
+ * decl.c (pushdecl_class_level): Likewise.
+
+ * decl.c (finish_enum): Set the type of all the enums.
+
+ * class.c (finish_struct): Don't get confused by access decls.
+
+ * cp-tree.h (TYPE_MAIN_DECL): New macro to get the _DECL for a
+ _TYPE. You can stop using TYPE_NAME for that now.
+
+ * parse.y: Lose doing_explicit (check $0 instead).
+ * gxx.gperf: 'template' now has a RID.
+ * lex.h (rid): Likewise.
+ * lex.c (init_lex): Set up the RID for 'template'.
+
+ * parse.y (type_specifier_seq): typed_typespecs or
+ nonempty_type_quals. Use it.
+ (handler_args): Fix bogus syntax.
+ (raise_identifier{,s}, optional_identifier): Lose.
+ * except.c (expand_start_catch_block): Use grokdeclarator to parse
+ the catch variable.
+ (init_exception_processing): The second argument to
+ __throw_type_match is ptr_type_node.
+
+ Fri May 6 07:18:54 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ change propagated from c-decl.c of snapshot 940429 ]
+ * cp/decl.c (finish_decl): Setting asmspec_tree should not
+ zero out the old RTL.
+
+Fri May 6 01:25:38 1994 Mike Stump <mrs@cygnus.com>
+
+ Add alpha exception handling support to the compiler.
+ Quick and dirty backend in except.c.
+
+ * cp/*: Remove most remnants of old exception handling support.
+ * decl.c (finish_function): Call expand_exception_blocks to put
+ the exception hanlding blocks at the end of the function.
+ * dec.c (hack_incomplete_structures): Make sure expand_decl_cleanup
+ comes after expand_decl_init.
+ * except.c: Reimplementation.
+ * expr.c (cplus_expand_expr): Handle THROW_EXPRs.
+ * lex.c (init_lex): Always have catch, try and throw be reserved
+ words, so that we may always parse exception handling.
+ * parse.y: Cleanup to support new interface into exception handling.
+ * tree.def (THROW_EXPR): Add.
+
+Thu May 5 17:35:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (simple_stmt, for loops): Use implicitly_scoped_stmt.
+ (various): Lose .kindof_pushlevel and partially_scoped_stmt.
+
+Thu May 5 16:17:27 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * parse.y (already_scoped_stmt): move expand_end_binding() to
+ fix the unmatched LBB/LBE in stabs.
+
+Thu May 5 14:36:17 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (set_nested_typename): Set TREE_MANGLED on the new
+ identifiers.
+ (pushdecl): Check TREE_MANGLED.
+ (xref_tag): Likewise.
+ * cp-tree.h (TREE_MANGLED): This identifier is a
+ DECL_NESTED_TYPENAME (named to allow for future use to denote
+ mangled function names as well).
+
+ Implement inconsistency checking specified in [class.scope0].
+ * decl.c (lookup_name_real): Don't set ICV here after all.
+ (finish_enum): Also set the type of the enumerators themselves.
+ (build_enumerator): Put the CONST_DECL in the list instead of its
+ initial value.
+ (pushdecl_class_level): Check inconsistent use of a name in the
+ class body.
+ * class.c (finish_struct): Check inconsistent use of a name in the
+ class body. Don't set DECL_CONTEXT on types here anymore.
+ * parse.y (qualified_type_name): Note that the identifier has now
+ been used (as a type) in the class body.
+ * lex.c (do_identifier): Note that the identifier has now been used
+ (as a constant) in the class body.
+ * error.c (dump_decl): Print type and enum decls better.
+
+Thu May 5 09:35:35 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck.c (build_modify_expr): Warn about assignment to `this'.
+
+Wed May 4 15:55:49 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (build_delete): Use the global operator delete when
+ requested.
+
+ * decl.c (lookup_name_real): If we find the type we're looking in a
+ base class while defining a class, set IDENTIFIER_CLASS_VALUE for
+ the type.
+
+ * class.c (finish_struct): Remove a couple of dependencies on
+ language linkage.
+
+ * decl.c (pushtag): Classes do nest in extern "C" blocks.
+ (pushdecl): Only set DECL_NESTED_TYPENAME on the canonical one for
+ the type.
+ (pushtag): Remove another dependency on the language linkage.
+
+ * lex.c (cons_up_default_function): Don't set DECL_CLASS_CONTEXT to
+ a const-qualified type.
+
+ * decl.c (push_overloaded_decl): Throw away built-in decls here.
+ (duplicate_decls): Instead of here.
+
+Wed May 4 15:27:40 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Do The Right
+ Thing (I hope) if we're using thunks.
+
+Wed May 4 13:52:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (specialization): aggr template_type_name ';'.
+ (named_class_head_sans_basetype): Use it.
+ (explicit_instantiation): Likewise.
+ (tmpl.2): Revert.
+
+ * cvt.c (build_type_conversion_1): Use convert_for_initialization,
+ rather than convert, to do conversions after the UDC.
+
+ * cp-tree.h (SHARED_MEMBER_P): This member is shared between all
+ instances of the class.
+
+ * search.c (lookup_field): If the entity found by two routes is the
+ same, it's not ambiguous.
+
+Wed May 4 12:10:00 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (lookup_name_real): Check for a NULL TREE_VALUE,
+ to prevent the compiler from crashing ...
+
+Wed May 4 11:19:45 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): If we don't have an object, check
+ basetype_path to figure out where to look up the function.
+
+ * typeck.c (convert_for_initialization): Pass TYPE_BINFO (type) to
+ build_method_call in case exp is NULL_TREE.
+
+Tue May 3 16:02:53 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ Give a vtable entries a unique named type, for the sake of gdb.
+ * class.c (build_vtable_entry): The addres of a thunk now has
+ type vtable_entry_type, not ptr_type_node.
+ * method.c (make_thunk): Fix type of THUNK_DECL.
+ * class.c (add_virtual_function, override_one_vtable): Use
+ vfunc_ptr_type_node, instead of ptr_type_node.
+ * cp-tree.h (vfunc_ptr_type_node): New macro.
+ * decl.c (init_decl_processing): Make vtable_entry_type
+ be a unique type of pointer to a unique function type.
+
+Tue May 3 09:20:44 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (do_explicit): Sets doing_explicit to 1.
+ (explicit_instantiation): Use do_explicit rather than TEMPLATE
+ directly, add "do_explicit error" rule.
+ (datadef): Set doing_explicit to 0 after an explicit instantiation.
+ (tmpl.2): Don't instantiate if we see a ';' unless we're doing an
+ explicit instantiation.
+ (named_class_head_sans_basetype): Remove aggr template_type_name
+ ';' again.
+
+Mon May 2 23:17:21 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * search.c (lookup_nested_tag): Lose.
+
+ * decl2.c (grokfield): Set DECL_CONTEXT on TYPE_DECLs.
+ (lookup_name_nonclass): Lose.
+
+ * decl.c (poplevel_class): Add force parameter.
+ (lookup_name_real): Fix handling of explicit scoping which specifies
+ a class currently being defined. Add 'nonclass' argument.
+ (lookup_name, lookup_name_nonclass): Shells for lookup_name_real.
+
+ * class.c (finish_struct): Don't unset IDENTIFIER_CLASS_VALUEs here.
+ (popclass): Force clearing of IDENTIFIER_CLASS_VALUEs if we're being
+ called from finish_struct.
+
+Mon May 2 19:06:21 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (init_decl_processing), cp-tree.h: Removed memptr_type.
+ (It seeems redundant, given build_ptrmemfunc_type.)
+ * typeck.c (get_member_function_from_ptrfunc), gc.c (build_headof,
+ build_classof): Use vtable_entry_type instead of memptr_type.
+ * method.c (emit_thunk): Call poplevel with functionbody==0
+ to prevent DECL_INITIAL being set to a BLOCK.
+
+Mon May 2 15:02:11 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (named_class_head_sans_basetype): Add "aggr
+ template_type_name ';'" rule for forward declaration of
+ specializations.
+
+Mon May 2 15:02:11 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (instantiate_type): Deal with pmf's.
+
+ * Make-lang.in (cc1plus): Don't depend on OBJS or BC_OBJS, since
+ stamp-objlist does.
+
+ * Makefile.in (../cc1plus): Depend on OBJDEPS.
+ (OBJDEPS): Dependency version of OBJS.
+
+Mon May 2 12:51:31 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * search.c (dfs_debug_mark): unmark TYPE_DECL_SUPPRESS_DEBUG, not
+ DECL_IGNORED_P.
+
+Fri Apr 29 12:29:56 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Clear out memory of local tags. And
+ typedefs.
+
+ * decl2.c (grokclassfn): Don't set DECL_CONTEXT to a cv-qualified
+ type.
+ * search.c (get_matching_virtual): Be more helpful in error message.
+
+ * *: Use DECL_ARTIFICIAL (renamed from DECL_SYNTHESIZED).
+
+ * lex.c (default_assign_ref_body): Expect TYPE_NESTED_NAME to work.
+ (default_copy_constructor_body): Likewise.
+
+ * class.c (finish_struct): Don't gratuitously create multiple decls
+ for nested classes.
+
+Thu Apr 28 23:39:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Avoid clobbering the arg types of other functions when reverting
+ static member functions.
+ * decl.c (revert_static_member_fn): Rearrange arguments, don't
+ require values for 'fn' and 'argtypes', add warning to comment
+ above.
+ (decls_match): Rearrange arguments in call to rsmf.
+ (grok_op_properties): Don't pass values for fn and argtypes.
+ * pt.c (instantiate_template): Don't pass values for fn and argtypes.
+
+Thu Apr 28 16:29:11 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * Make-lang.in (cc1plus): Depend on stamp-objlist.
+ * Makefile.in (BC_OBJS): Delete.
+ (OBJS): Cat ../stamp-objlist to get language independent files.
+ Include ../c-common.o.
+ (../cc1plus): Delete reference to BC_OBJS.
+
+Thu Apr 28 02:12:08 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * search.c (compute_access): No really, deal with static members
+ properly. Would I lie to you?
+
+ Implement lexical hiding of function declarations.
+ * pt.c (tsubst): Use lookup_name to look for function decls to guide
+ instantiation.
+ * method.c (build_opfncall): Use lookup_name_nonclass to look for
+ non-member functions.
+ * init.c (do_friend): Use lookup_name_nonclass to look for
+ functions.
+ * error.c (ident_fndecl): Use lookup_name to look for functions.
+ * decl2.c (lookup_name_nonclass): New function, skips over
+ CLASS_VALUE.
+ * decl.c (struct binding_level): Lose overloads_shadowed field.
+ (poplevel): Don't deal with overloads_shadowed.
+ (push_overloaded_decl): Do lexical hiding for functions.
+ * class.c (instantiate_type): Don't check non-members if we have
+ members with the same name.
+ * call.c (build_method_call): Use lookup_name_nonclass instead of
+ IDENTIFIER_GLOBAL_VALUE to check for non-member functions.
+ (build_overload_call_real): Likewise.
+
+ * decl.c (duplicate_decls): Check for ambiguous overloads here.
+ (push_overloaded_decl): Instead of here.
+
+ * decl.c (pushdecl): Back out Chip's last change.
+
+ * decl.c (grok_op_properties): operators cannot be static members.
+
+ * cp-tree.h (DECL_SYNTHESIZED): DECL_SOURCE_LINE == 0
+ (SET_DECL_SYNTHESIZED): DECL_SOURCE_LINE = 0
+ * lex.c (cons_up_default_function): Use SET_DECL_SYNTHESIZED.
+
+ * method.c (do_inline_function_hair): Don't put friends of local
+ classes into global scope, either.
+
+ * typeck2.c (build_functional_cast): Don't look for a function call
+ interpretation.
+
+Thu Apr 28 15:19:46 1994 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h: disable use of backend EH.
+
+Wed Apr 27 21:01:24 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * Make-lang.in (c++.distdir): mkdir tmp/cp first.
+ * Makefile.in (INCLUDES): Move definition to same place as
+ parent makefile.
+ (ALLOCA): Define.
+ (OLDAR_FLAGS): Delete.
+ (OLDCC): Define.
+ (DIR): Delete.
+ (CLIB): Define.
+ (####site): Delete.
+ (SUBDIR_USE_ALLOCA): Don't use ALLOCA if compiling with gcc.
+
+Wed Apr 27 19:10:04 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * decl.c (xref_tag): not to use strstr(), it's not available on
+ all platforms.
+
+Wed Apr 27 18:10:12 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Resolve yet another class/pmf confusion.
+
+ * call.c (build_overload_call_real): Don't take the single-function
+ shortcut if we're dealing with an overloaded operator.
+
+Wed Apr 27 17:35:37 1994 Mike Stump <mrs@cygnus.com>
+
+ * search.c (get_base_distance): Search the virtual base class
+ binfos, incase someone wants to convert to a real virtual base
+ class.
+ * search.c (expand_indirect_vtbls_init): Use convert_pointer_to_real
+ instead of convert_pointer_to, as it now will work.
+
+Wed Apr 27 15:36:49 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): Don't complain about casting away
+ const and volatile.
+
+ * typeck.c (build_unary_op): References are too lvalues.
+
+Wed Apr 27 13:58:05 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (override_one_vtable): We have to prepare_fresh_vtable
+ before we modify it, not after, also, we cannot reuse an old vtable,
+ once we commit to a new vtable. Implement ambiguous overrides in
+ virtual bases as abstract. Hack until we make the class
+ ill-formed.
+
+Wed Apr 27 01:17:08 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (unary_expr): Expand new_placement[opt] and
+ new_initializer[opt] inline.
+
+ * search.c (lookup_fnfields): Don't throw away the inheritance
+ information here, either.
+ (compute_access): Handle static members properly.
+
+ * init.c (build_member_call): Always set basetype_path, and pass it
+ to lookup_fnfields.
+
+ * search.c (lookup_field): Deal properly with the case where
+ xbasetype is a chain of binfos; don't throw away the inheritance
+ information.
+ (compute_access): protected_ok always starts out at 0.
+
+ * init.c (resolve_offset_ref): Don't cast `this' to the base type
+ until we've got our basetype_path.
+
+ * cp-tree.h (IS_OVERLOAD_TYPE): aggregate or enum.
+
+ * cvt.c (build_up_reference): Use build_pointer_type rather than
+ TYPE_POINTER_TO.
+
+ * call.c (convert_harshness_ansi): Call type_promotes_to for reals
+ as well.
+
+ * cvt.c (type_promotes_to): Retain const and volatile, add
+ float->double promotion.
+
+ * decl.c (grokdeclarator): Don't bash references to arrays into
+ references to pointers in function parms. Use type_promotes_to.
+
+Tue Apr 26 23:44:36 1994 Mike Stump <mrs@cygnus.com>
+
+ Finish off Apr 19th work.
+
+ * class.c (finish_struct_bits): Rename has_abstract_virtuals to
+ might_have_abstract_virtuals.
+ * class.c (strictly_overrides, override_one_vtable,
+ merge_overrides): New routines to handle virtual base overrides.
+ * class.c (finish_struct): Call merge_overrides to handle overrides
+ in virtual bases.
+
+Tue Apr 26 12:45:53 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_function_call): Call build_function_call_real with
+ LOOKUP_NORMAL.
+
+ * *: Don't deal with TYPE_EXPRs.
+
+ * tree.c (lvalue_p): If the type of the expression is a reference,
+ it's an lvalue.
+
+ * cvt.c (convert_to_reference): Complain about passing const
+ lvalues to non-const references.
+ (convert_from_reference): Don't arbitrarily throw away const and
+ volatile on the target type.
+
+ * parse.y: Simplify and fix rules for `new'.
+
+ * decl.c (grok_op_properties): operator void is illegal.
+
+Mon Apr 25 02:36:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (components): Anonymous bitfields can still have declspecs.
+
+ * decl.c (pushdecl): Postpone handling of function templates like we
+ do C functions.
+
+ * search.c (expand_indirect_vtbls_init): Fix infinite loop when
+ convert_pointer_to fails.
+
+ * call.c (compute_conversion_costs_ansi): A user-defined conversion
+ by itself is better than that UDC followed by standard conversions.
+ Don't treat integers and reals specially.
+
+ * cp-tree.h: Declare flag_ansi.
+
+ * typeck.c (c_expand_return): pedwarn on return in void function
+ even if the expression is of type void.
+ (build_c_cast): Don't do as much checking for casts to void.
+ (build_modify_expr): pedwarn about array assignment if this code
+ wasn't generated by the compiler.
+
+ * tree.c (lvalue_p): A comma expression is an lvalue if its second
+ operand is.
+
+ * typeck.c (default_conversion): Move code for promoting enums and
+ ints from here.
+ * cvt.c (type_promotes_to): To here.
+ * call.c (convert_harshness_ansi): Use type_promotes_to. Also fix
+ promotion semantics for reals.
+
+Sun Apr 24 16:52:51 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * Make-lang.in (c++.install-common): Check for g++-cross.
+ * Makefile.in: Remove Cygnus cruft.
+ (config.status): Delete.
+ (RTL_H): Define.
+ (TREE_H): Use complete pathname, some native makes have minimal
+ VPATH support.
+ (*.o): Use complete pathname to headers in parent dir.
+ (doc, info, dvi): Delete.
+
+Sun Apr 24 16:52:51 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * Make-lang.in (c++.install-common): Check for g++-cross.
+ * Makefile.in: Remove Cygnus cruft.
+ (config.status): Delete.
+ (RTL_H): Define.
+ (TREE_H): Use complete pathname, some native makes have minimal
+ VPATH support.
+ (*.o): Use complete pathname to headers in parent dir.
+ (doc, info, dvi): Delete.
+
+Sun Apr 24 00:47:49 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (pushdecl): Avoid redundant warning on redeclaring function
+ with different return type.
+ (decls_match): Compare return types strictly.
+
+Fri Apr 22 12:55:42 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (build_type_conversion): Do try to convert through other
+ pointers. This will fail if the class defines multiple pointer
+ conversions.
+
+ * error.c (dump_type_prefix): Print out pointers to arrays properly.
+ (dump_type_suffix): Likewise. (was 'int *[]', now 'int (*)[]')
+
+ * typeck.c (build_unary_op): Disallow ++/-- on pointers to
+ incomplete type.
+
+ * decl.c (duplicate_decls): Check mismatched TREE_CODES after
+ checking for shadowing a builtin. If we're redeclaring a builtin
+ function, bash the old decl to avoid an ambiguous overload.
+
+ * cvt.c (convert_to_reference): Don't force arrays to decay here.
+
+ * tree.c (lvalue_p): A MODIFY_EXPR is an lvalue.
+
+ * decl.c (duplicate_decls): Don't assume that the decls will have
+ types.
+
+ Mon Apr 18 11:35:32 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940318 snapshot ]
+ * c-decl.c (pushdecl): Warn if type mismatch with another external decl
+ in a global scope.
+
+ Fri Apr 22 06:38:56 1994 Chip Salzenberg <chip@fin.uucp>
+
+ * cp/typeck2.c (signature_error): Use cp_error for "%T".
+
+ Mon Apr 18 11:59:59 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940415 snapshot ]
+ * cp/decl.c (duplicate_decls, pushdecl, builtin_function):
+ Use DECL_FUNCTION_CODE instead of DECL_SET_FUNCTION_CODE.
+
+ Mon Apr 18 11:55:18 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940409 snapshot ]
+ * cp/decl.c (duplicate_decls): Put new type in same obstack as
+ old ones, or permanent if old ones in different obstacks.
+
+ Mon Apr 18 11:48:49 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940401 snapshot ]
+ * cp/parse.y (attrib): Handle string args as expressions,
+ merging the two rules. `mode' attribute now takes a string arg.
+ Delete the rule for an identifier as arg.
+
+ Mon Apr 18 11:24:00 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940312 snapshot ]
+ * cp/typeck.c (pointer_int_sum): Multiplication should be done signed.
+ (pointer_diff): Likewise the division.
+
+ Sun Mar 6 19:43:39 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940304 snapshot ]
+ * cp/decl.c (finish_decl): Issue warning for large objects,
+ if requested.
+
+ Sat Feb 19 22:20:32 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940218 snapshot ]
+ * cp/parse.y (attrib): Handle attribute ((section ("string"))).
+ * cp/decl.c (duplicate_decls): Merge section name into new decl.
+
+ Tue Feb 8 09:49:17 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940206 snapshot ]
+ * cp/typeck.c (signed_or_unsigned_type): Check for any
+ INTEGRAL_TYPE_P not just INTEGER_TYPE.
+
+ Mon Dec 6 13:35:31 1993 Norbert Kiesel (norbert@i3.INformatik.rwth-aachen.DE)
+
+ * cp/decl.c (finish_enum): Start from 0 when determining precision
+ for short enums.
+
+ Fri Dec 3 17:07:58 1993 Ralph Campbell (ralphc@pyramid.COM)
+
+ * cp/parse.y (unary_expr): Look at $1 for tree_code rather than
+ casting $$.
+
+ Wed Nov 17 19:22:09 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp/typeck.c (build_binary_op_nodefault): Propagate code
+ from C front-end to optimize unsigned short division.
+ (build_conditional_expr): Fix bug in "1 ? 42 : (void *) 8".
+
+ Wed Nov 17 19:17:18 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp/call.c (convert_harshness_ansi): Given an (e.g.) char
+ constant, prefer 'const char &' to 'int'.
+
+ Wed Feb 3 13:11:48 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp/class.c (finish_struct_methods): Handle multiple
+ constructors in fn_fields list.
+
+Fri Apr 22 12:48:10 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * class.c (finish_struct): use TYPE_DECL_SUPPRESS_DEBUG to flag
+ types not to be dumped in stabs, like types in #pragma interface.
+ * decl.c (init_decl_processing): use TYPE_DECL_SUPPRESS_DEBUG to
+ mark unknown type.
+
+Fri Apr 22 03:27:26 1994 Doug Evans <dje@cygnus.com>
+
+ * Language directory reorganization.
+ See parent makefile.
+
+Thu Apr 21 18:27:57 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * cp-tree.h (THUNK_DELTA): It is normally negative, so
+ use signed .i variant of frame_size rather than unsigned .u.
+ * cp-tree.h (VTABLE_NAME_FORMAT): If flag_vtable_thunks,
+ use "VT" rather than "vt" due to binary incompatibility.
+ * class.c (get_vtable_name): Use strlen of VTABLE_NAME_FORMAT,
+ rather than sizeof, since it is now an expression.
+ * class.c (modify_one_vtable): Modify to skip initial element
+ containing a count of the vtable.
+
+Thu Apr 21 00:09:02 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (check_newline): Force interface_unknown on main input file.
+
+ * pt.c (do_pending_expansions): Always emit functions that have been
+ explicitly instantiated.
+ (do_function_instantiation): Set DECL_EXPLICITLY_INSTANTIATED.
+ (do_type_instantiation): Set CLASSTYPE_VTABLE_NEEDS_WRITING and
+ DECL_EXPLICITLY_INSTANTIATED on all my methods.
+ * parse.y (explicit_instantiation): Call do_type_instantiation for
+ types.
+ * decl2.c (finish_vtable_vardecl): Call import_export_vtable.
+ * decl.c (start_function): Don't set DECL_EXTERNAL on a function
+ that has been explicitly instantiated.
+ * cp-tree.h (DECL_EXPLICITLY_INSTANTIATED): Alias for
+ DECL_LANG_FLAG_4.
+ * class.c: Move import_export_vtable to decl2.c, and comment out all
+ uses.
+
+Wed Apr 20 16:51:06 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (process_next_inline): Don't muck with DECL_INLINE.
+ (do_pending_inlines): Likewise.
+
+Tue Apr 19 22:25:41 1994 Mike Stump <mrs@cygnus.com>
+
+ Reimplement vtable building, and most vtable pointer setting.
+ Allows for earier maintenance, easier understandability, and most
+ importantly, correct semantics.
+
+ * class.c (build_vtable): Removed unneeded
+ SET_BINFO_VTABLE_PATH_MARKED.
+ * class.c (prepare_fresh_vtable): Likewise. Added argument.
+ * class.c (modify_vtable_entry): General cleanup.
+ * class.c (related_vslot, is_normal, modify_other_vtable_entries,
+ modify_vtable_entries): Removed.
+ * class.c (add_virtual_function): General cleanup.
+ * class.c (finish_base_struct): Setup BINFO_VTABLE and
+ BINFO_VIRTUALS as early as we can, so that modify_all_vtables can
+ work.
+ * class.c (finish_vtbls): New routine, mostly from
+ unmark_finished_struct.
+ * class.c (overrides): New routine.
+ * class.c (modify_one_vtable): New routine, mostly from
+ modify_other_vtable_entries and modify_vtable_entries.
+ * class.c (modify_all_direct_vtables, modify_all_indirect_vtables,
+ modify_all_vtables): New routines.
+ * class.c (finish_struct): Added arguemnt to prepare_fresh_vtable
+ call. General cleanup on how pending_hard_virtuals are handled.
+ General cleanup on modifying vtables. Use finish_vtbls, instead of
+ unmark_finished_struct.
+ * cp-tree.h (init_vtbl_ptrs, expand_direct_vtbls_init,
+ get_first_matching_virtual, get_matching_virtual,
+ expand_vbase_vtables_init, expand_indirect_vtbls_init): Update.
+ * cvt.c (convert_pointer_to_real): cleanup error message.
+ * decl.c (grokfndecl): General cleanup.
+ * decl.c (finish_function): Change init_vtbl_ptrs call to
+ expand_direct_vtbls_init. Change expand_vbase_vtables_init call to
+ expand_indirect_vtbls_init.
+ * init.c (expand_virtual_init): Remove unneeded argument.
+ * init.c (init_vtbl_ptrs): Rename to expand_direct_vtbls_init, added
+ two arguments to make more general. Made more general. Now can be
+ used for vtable pointer initialization from virtual bases.
+ * init.c (emit_base_init): Change expand_vbase_vtables_init call to
+ expand_indirect_vtbls_init. Change init_vtbl_ptrs call to
+ expand_direct_vtbls_init.
+ * init.c (expand_virtual_init): General cleanup.
+ * init.c (expand_default_init): Change expand_vbase_vtables_init
+ call to expand_indirect_vtbls_init.
+ * init.c (expand_recursive_init_1): Change expand_vbase_vtables_init
+ call to expand_indirect_vtbls_init.
+ * init.c (expand_recursive_init): Change expand_vbase_vtables_init
+ call to expand_indirect_vtbls_init.
+ * search.c (get_first_matching_virtual): Rename to
+ get_matching_virtual. General cleanup and remove setting of
+ DECL_CONTEXT. That is now done in a cleaner way in
+ modify_vtable_entry and add_virtual_function.
+ * search.c (expand_vbase_vtables_init): Rename to
+ expand_indirect_vtbls_init. General cleanup. Use
+ expand_direct_vtbls_init to do hard work. Ensures that _all_ vtable
+ pointers from virtual bases are set up.
+ * search.c (bfs_unmark_finished_struct, unmark_finished_struct):
+ Removed.
+
+ * *.[chy]: Remove support for VTABLE_USES_MASK.
+
+Tue Apr 19 12:51:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): Use NOP_EXPRs to switch between
+ reference and pointer types instead of bashing the types directly.
+
+ * call.c (build_overload_call_real): Use the TREE_CODE to determine
+ whether the function is overloaded or not, rather than
+ TREE_OVERLOADED.
+ * *: Remove all uses of TREE_OVERLOADED.
+
+ * decl.c (grokdeclarator): Only complain about initializing const
+ fields when -ansi or -pedantic.
+
+Tue Apr 19 12:42:42 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * cp-tree.h (THUNK_DELTA): frame_size is now a union.
+
+Mon Apr 18 00:17:13 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Do overloading on a block-by-block basis, not function-by-function.
+ * decl.c: Lose overloads_to_forget.
+ (struct binding_level): Add overloads_shadowed field.
+ (poplevel): Restore overloads_shadowed.
+ (push_overloaded_decl): Use overloads_shadowed instead of
+ overloads_to_forget.
+ (finish_function): Don't look at overloads_to_forget.
+
+ Copy enum_overflow logic from c-decl.c.
+ * decl.c (start_enum): Initialize enum_overflow.
+ (build_enumerator): Use enum_overflow. Also use current_scope().
+
+ * search.c (current_scope): Move Brendan's comment from
+ build_enumerator here.
+
+ * typeck.c (convert_for_assignment): Change warnings to pedwarns for
+ discarding const/volatile.
+
+Sat Apr 16 01:18:21 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (comp_target_parms): Accept TEMPLATE_TYPE_PARMs on the rhs.
+ (comp_target_types): Likewise.
+
+ * decl.c (lookup_name): Don't unset got_scope here.
+
+ * spew.c (yylex): Only replace yylval with the TYPE_NESTED_NAME if
+ got_scope != NULL_TREE.
+
+Fri Apr 15 16:36:33 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Horrible kludge to prevent templates from being instantiated by
+ their base classes.
+ * parse.y (template_instantiate_once): Unset TYPE_BEING_DEFINED
+ before we get to left_curly.
+ * pt.c (instantiate_class_template): Set TYPE_BEING_DEFINED.
+
+ * error.c (dump_decl): If it's a typedef, print out the name of the
+ decl, not just the underlying type.
+
+ * decl.c (pushdecl): If the old duplicate decl was a TYPE_DECL,
+ update the IDENTIFIER_TYPE_VALUE of its name.
+
+ * decl2.c (finish_file): When processing the initializer for a
+ static member, pretend that the dummy function is a member of the
+ same class.
+
+Fri Apr 15 15:56:35 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * class.c (build_vtable_entry): revert Apr 4 change.
+ * decl2.c (mark_vtable_entries): replace pure virtual function
+ decl with abort's.
+
+Fri Apr 15 13:49:33 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_conditional_expr): Pedwarn on pointer/integer
+ mismatch, and don't pedwarn on 0/function pointer mismatch.
+
+ * typeck2.c (digest_init): Lose code for special handling of unions.
+ (process_init_constructor): Since they're handled just fine here.
+ Pedwarn on excess elements.
+
+ * decl2.c (grokfield): Complain about local class method declaration
+ without definition.
+
+Fri Apr 15 13:19:40 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * method.c (emit_thunk): Add extern declaration for
+ current_call_is_indirect (needed for hppa).
+
+Thu Apr 14 16:12:31 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Improve local class support; allow classes in different blocks to
+ have the same name.
+ * decl.c (pushtag): Support local classes better.
+ (pushdecl_nonclass_level): New function for pushing mangled decls of
+ nested types into the appropriate scope.
+ (xref_defn_tag): Use pushdecl_nonclass_level instead of
+ pushdecl_top_level.
+ (grokfndecl): Don't mess with IDENTIFIER_GLOBAL_VALUE for local
+ class methods.
+ * method.c (do_inline_function_hair): Likewise.
+
+ * class.c (finish_struct): It is legal for a class with no
+ constructors to have nonstatic const and reference members.
+
+Thu Apr 14 07:15:11 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (push_overloaded_decl): Avoid giving errors about
+ built-ins, since duplicate_decls will have given warnings/errors
+ for them.
+
+Thu Apr 14 03:45:12 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): Warn about casting pointer type to
+ reference type when this is probably not what they wanted.
+
+Wed Apr 13 13:12:35 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (finish_decl): Don't mindlessly set TREE_USED for
+ static consts any more (toplev.c has now been modified to
+ not emit warnings if they are unused).
+
+Wed Apr 13 00:22:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grok_op_properties): If op new/delete get here with
+ METHOD_TYPEs, do a revert_static_member_fn.
+
+ * cp-tree.h (IDENTIFIER_CLASS_TYPE_VALUE): Lose.
+ * init.c (is_aggr_typedef): Don't look at
+ IDENTIFIER_CLASS_TYPE_VALUE.
+ (get_aggr_from_typedef): Likewise.
+ (get_type_value): Likewise.
+ * call.c (build_scoped_method_call): Don't rely on overloaded
+ template names having IDENTIFIER_CLASS_VALUE set.
+
+ * parse.y (component_decl_1, fn.def2): Revert rules for
+ constructors.
+ (component_decl_1, fn.def2): Use $1 instead of $$, since $$ is being
+ clobbered.
+
+ * decl.c (start_function): Only warn about `void main()' if pedantic
+ || warn_return_type.
+
+Tue Apr 12 02:14:17 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Clean up overloading of the template name.
+ * class.c (pushclass): overload the template name whenever pushing
+ into the scope of a template class, not just if it is
+ uninstantiated.
+ (popclass): Correspondingly.
+ * search.c (push_class_decls): Don't overload_template_name.
+ * pt.c (overload_template_name): Don't set IDENTIFIER_LOCAL_VALUE or
+ DECL_CONTEXT on things.
+ * parse.y (left_curly): Don't overload_template_name.
+ * class.c (finish_struct): Don't undo_template_name_overload.
+
+ * method.c (build_opfncall): Only pass one argument to global op
+ delete.
+
+ * call.c (build_method_call): Use TYPE_VEC_DELETE_TAKES_SIZE to
+ decide how many arguments to use for vec delete.
+
+ * decl.c (grok_op_properties): Be consistent in modifying
+ current_class_type.
+ (grokdeclarator): Only complain about function decls with no return
+ type if we're being pedantic.
+
+Mon Apr 11 00:10:53 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Add support for operator new [] and operator delete [].
+
+ * tree.def: Add VEC_NEW_EXPR and VEC_DELETE_EXPR.
+ * ptree.c (print_lang_type): Indicate vec new/delete.
+ * parse.y: Support vec new/delete.
+ * method.c (build_decl_overload): Deal with vec new/delete.
+ (build_opfncall): Likewise.
+ * lex.c (init_lex): Set up values of ansi_opname and opname_tab for
+ vec new/delete. vec new uses "__vn", and vec delete uses "__vd".
+ * init.c (init_init_processing): Set up BIVN and BIVD.
+ (do_friend): Don't clean up after mistaken setting of TREE_GETS_NEW,
+ since it doesn't happen any more.
+ (build_new): Support vec new. Always call something.
+ (build_x_delete): Support vec delete.
+ (build_vec_delete): Lose dtor_dummy argument, add use_global_delete,
+ and pass it to build_x_delete.
+ * decl2.c (delete_sanity): Don't change behavior by whether or not
+ the type has a destructor. Pass use_global_delete to
+ build_vec_delete.
+ (coerce_delete_type): Make sure that the type returned has a first
+ argument of ptr_type_node.
+ * decl.c (init_decl_processing): Also declare the global vec
+ new/delete.
+ (grokdeclarator): Also force vec new/delete to be static.
+ (grok_op_properties): Note presence of vec new/delete, and play with
+ their args. If vec delete takes the optional size_t argument, set
+ TYPE_VEC_DELETE_TAKES_SIZE.
+ * cp-tree.h (TYPE_GETS_{REG,VEC}_DELETE): New macros to simplify
+ checking for one delete or the other.
+ (lang_type): gets_new and gets_delete are now two bits long. The
+ low bit is for the non-array version. Lose gets_placed_new.
+ (TYPE_VEC_DELETE_TAKES_SIZE): New macro indicating that the vec
+ delete defined by this class wants to know how much space it is
+ deleting.
+ (TYPE_VEC_NEW_USES_COOKIE): New macro to indicate when vec new must
+ add a header containing the number of elements in the vector; i.e.
+ when the elements need to be destroyed or vec delete wants to know
+ the size.
+ * class.c (finish_struct_methods): Also check for overloading vec
+ delete.
+ * call.c (build_method_call): Also delete second argument for vec
+ delete.
+
+ * decl.c (grokdeclarator): Correct complaints again.
+ (grokdeclarator): Fix segfault on null declarator.
+ (decls_match): Also accept redeclaration with no arguments if both
+ declarations were in C context. Bash TREE_TYPE (newdecl) here.
+ (duplicate_decls): Instead of here.
+
+ * parse.y (nested_name_specifier_1): Lose rules for dealing with
+ syntax errors nicely, since they break parsing of 'const i;'.
+
+ * decl.c (lookup_name): if (got_scope == current_class_type)
+ val = IDENTIFIER_CLASS_VALUE (name).
+
+ * search.c (lookup_nested_tag): Look in enclosing classes, too.
+
+ * spew.c (yylex): Only look one character ahead when checking for a
+ SCOPE.
+
+ * lex.c (check_newline): Read first nonwhite char before
+ incrementing lineno.
+
+ * decl.c (grokdeclarator): Don't claim that typedefs are variables
+ in warning.
+
+ * parse.y: Divide up uses of unqualified_id into
+ notype_unqualified_id and unqualified_id, so that TYPENAME can be
+ used as an identifier after an object.
+
+ * class.c (push_nested_class): Don't push into non-class scope.
+
+ * decl.c (grokdeclarator): If an identifier could be a type
+ conversion operator, but has no associated type, it's not a type
+ conversion operator.
+
+ * pt.c (unify): Check for equality of constants better.
+
+ * decl.c (grokdeclarator): Don't complain about access decls.
+
+Sun Apr 10 02:39:55 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): pedwarn about data definitions without
+ types here.
+
+ * parse.y (datadef): Don't pedwarn about decls without types here,
+ since that is valid for functions.
+ (fn.def2, component_decl): Support constructors with declmods again.
+ (nomods_initdecls): For decls without any mods, so that we don't try
+ to get declspecs from some arbitrary $0.
+
+ * search.c (lookup_field): Use cp_error.
+
+ * parse.y (nested_name_specifier_1): Don't check aggr/non-aggr type
+ here; it breaks destructors for non-aggr types.
+
+ * decl.c (lookup_name): Only look for TYPE_DECLs in base classes of
+ a type being defined, like the comment says.
+ If got_scope is not an aggregate, just return NULL_TREE.
+
+ * pt.c (create_nested_upt): Kung's code for creating types nested
+ within uninstantiated templates now lives here (it used to live in
+ hack_more_ids). It needs to be expanded.
+
+ * parse.y: Stop calling see_typename so much.
+
+ * decl.c (lookup_name): Deal with TTPs and UPTs.
+
+ * lex.c (real_yylex): Don't set looking_for_typename just because we
+ saw a 'new'.
+ (dont_see_typename): #if 0 out.
+
+ * spew.c (yylex): Increment looking_for_typename if the next
+ character is SCOPE, rather than setting it to 1; this way, the value
+ from seeing an aggr specifier will not be lost. This kinda relies
+ on looking_for_typename never being < 0, which is now true.
+
+ * parse.y (nested_name_specifier_1): Accept TEMPLATE_TYPE_PARMs,
+ too.
+ (named_class_head_sans_basetype): Accept template types, too. Oops.
+
+Fri Apr 8 16:39:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (reparse_decl_as_expr1): Handle SCOPE_REFs.
+
+ * parse.y: Lose START_DECLARATOR.
+
+ * search.c (lookup_nested_tag): New function to scan CLASSTYPE_TAGS
+ for a class.
+
+ * parse.y: Simplify fn.def2 and component_decl. Support 'enum
+ A::foo' syntax. Catch invalid scopes better.
+
+ * parse.y, lex.c: lose TYPENAME_COLON.
+
+ * decl2.c (groktypefield): #if 0 out.
+
+ * decl.c (lookup_name): If the type denoted by got_scope is
+ currently being defined, look in CLASSTYPE_TAGS rather than FIELDS.
+
+ * class.c (push_nested_class): Don't try to push into
+ error_mark_node.
+
+Fri Apr 8 07:26:36 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * Makefile.in (stamp-parse): Update count of conflicts to 33.
+
+Thu Apr 7 17:47:53 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ A saner implementation of nested types that treats template types
+ no differently from non-template types. There are still some
+ shortcomings of our system; most notably, it is difficult to look
+ for a nested type that is hidden by another name, because of the way
+ we keep track of hidden types. But this shouldn't be a problem for
+ just about anyone. Perhaps lookup_field should be fixed up a bit.
+
+ * spew.c: Moved handling of nested types/scoping from the lexer
+ into the parser. Removed variable template_type_seen_before_scope.
+ Removed functions frob_identifier, hack_more_ids, and various cruft
+ that was #if 0'd out in the past, reducing the size of the file from
+ 1146 lines to 450 lines. We can't quite do away with spew.c yet,
+ though; we still need it for do_aggr () and checking for SCOPE after
+ the current identifier. And setting lastiddecl.
+
+ * parse.y: Moved handling of nested types/scoping from the lexer
+ into the parser, using a new global variable `got_scope'. Reduced
+ the number of states by 53. Implemented all uses of explicit global
+ scope. Removed terminals SCOPED_TYPENAME and SCOPED_NAME. Removed
+ nonterminals tmpl.1, scoped_base_class, id_scope, typename_scope,
+ scoped_typename. Added nonterminals nested_type,
+ qualified_type_name, complete_type_name, qualified_id, ptr_to_mem,
+ nested_name_specifier, global_scope, overqualified_id, type_name.
+ Changed many others. Added 9 new reduce/reduce conflicts, which are
+ nested type parallels of 9 that were already in the grammar for
+ non-nested types. Eight of the now 33 conflicts should be removed
+ in the process of resolving the late binding between variable and
+ function decls.
+
+ * gxxint.texi (Parser): Update.
+
+ * cp-tree.h (IS_AGGR_TYPE_CODE): Add UNINSTANTIATED_P_TYPE.
+
+ * lex.h: Add decl for got_scope.
+
+ * lex.c (see_typename): Claim to be the lexer when calling
+ lookup_name.
+
+ * decl.c (lookup_name): When called from the lexer, look at
+ got_scope and looking_at_typename; otherwise don't.
+
+Thu Apr 7 22:05:47 1994 Mike Stump <mrs@cygnus.com>
+
+ 31th Cygnus<->FSF merge.
+
+Thu Apr 7 17:47:53 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (mark_vtable_entries): Call this to mark all the
+ entries in the vtable addressable.
+ (finish_decl_parsing): Handle SCOPE_REFs.
+
+ * decl.c (decls_match): Always call compparms with strict == 1.
+ Handle the special case of C function redecl here.
+ (duplicate_decls): Only keep the old type if the new decl takes no
+ arguments.
+
+ * typeck.c (compparms): Also allow t1 to be ... if strict == 0.
+
+Thu Apr 7 16:17:50 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (build_vtable_entry): Fix breakage introduced Apr 5
+ 17:48:41.
+
+Wed Apr 6 16:05:10 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * init.c (build_virtual_init), search.c (build_vbase_vtables_init),
+ ch-tree.h: Every place these functions were called, the result was
+ immediately passed to expand_expr_stmt. Reduce redundancy by
+ calling expand_expr_init *inside* these functions. These
+ makes for a simpler interface, and we don't have to build
+ compound expressions. Hence, rename these function to:
+ expand_virtual_init and expand_vbase_vtables_init respectively.
+ * init.c, decl.c: Change callers of these functions.
+ * init.c, cp-tree.h (expand_virtual_init): Make static.
+
+ * decl2.c (finish_file): Check TREE_PUBLIC||TREE_ADDRESSABLE
+ rather than DECL_SAVED_INSNS before emitting inlines.
+
+Wed Apr 6 13:06:39 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * spew.c (init_spew): #if 0 out stuff used by arbitrate_lookup.
+
+ * decl.c (duplicate_decls): If this is a new declaration of an
+ extern "C" function, keep the type (for the argtypes).
+ (redeclaration_error_message): Don't check DECL_LANGUAGE here.
+ (decls_match): Call compparms with a value of strict dependent on
+ the value of strict_prototypes for DECL_LANGUAGE (oldecl).
+
+ * typeck.c (compparms): ... is only equivalent to non-promoting
+ parms if we're not being strict.
+
+ * parse.y (empty_parms): Don't check flag_ansi || pedantic here.
+
+ * decl.c (init_decl_processing): if (flag_ansi || pedantic)
+ strict_prototypes_lang_c = strict_prototypes_lang_cplusplus;
+
+ * decl2.c (grok_function_init): Don't set DECL_INITIAL on pure
+ virtuals.
+
+Tue Apr 5 17:48:41 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ Support for implementing vtables with thunks.
+ * tree.def (THUNK_DECL): New TREE_CODE.
+ * cp-tree.h (FNADDR_FROM_VTABLE_ENTRY), tree.c
+ (fnaddr_from_vtable_entry): Handle flag_vtable_thunks case.
+ * cp-tree.h (memptr_type): New variable.
+ * class.c (build_vtable_entry): Build thunk if necessary.
+ * class.c (build_vfn_ref): If using thunks, don't need
+ to add delta field from vtable (there is none!).
+ * decl.c: Add memptr_type as well as vtable_entry_type.
+ If using thunks, the latter is just ptr_type_node.
+ * gc.c, typeck.c: Use memptr_typeChange, not vtable_entry_type.
+ * decl2.c (finish_vtable_vardecl): Handle thunks.
+ * expr.c (cplus_expand_expr): Support THUNK_DECL.
+
+ * decl.c (grokdeclarator): Set DECL_THIS_EXTERN if "extern".
+ * decl.c (start_function): Set current_extern_inline based on
+ DECL_THIS_EXTERN, not TREE_PUBLIC.
+ * decl.c (finish_function): Call mark_inline_for_output if needed,
+
+ Improve intelligence about when to emit inlines.
+ * cp-tree.h (lang_decl_flags): New field saved_inline.
+ * cp-tree.h (DECL_SAVED_INLINE): New macro.
+ * class.c (add_virtual_function): Don't set TREE_ADDRESSABLE.
+ * decl.h, decl.c (pending_addressable_inlines): Removed.
+ * decl2.c (pending_addressable_inlines): Renamed to saved_inlines.
+ * decl2.c (mark_inline_for_output): Do nothing if
+ DECL_SAVED_INLINE; otherwise set it (and add to saved_inlines list).
+ * decl2.c (finish_vtable_vardecl): SET_CLASSTYPE_INTERFACE_KNOWN
+ and set CLASSTYPE_INTERFACE_ONLY if there is a non-inline virtual.
+ * decl2.c (finish_file): Writing out inlines later, so we can
+ also handle the ones needed for vtbales.
+ * decl2.c (write_vtable_entries, finish_vtable_typedecl): Removed.
+
+ * cp-tree.h, class.c, decl2.c, search.c: Remove -fvtable-hack
+ and flag_vtable_hack. Use -fvtable-thunks and flag_vtable_thunks
+ instead. (The rationale is that these optimizations both break binary
+ compatibility, but should become the default in a future release.)
+
+Wed Apr 6 10:53:56 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (modify_vtable_entries): Never reset the DECL_CONTEXT
+ of a fndecl, as we might not be from that vfield.
+
+Tue Apr 5 17:43:35 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * class.c (add_virtual_function): fix bug for pure virtual, so
+ that DECL_VINDEX of the dummy decl copied won't be error.
+ (see also Apr 4 change)
+
+Tue Apr 5 17:23:45 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * typeck.c (c_expand_return): Before checking that we're not
+ returning the address of a local, make sure it's a VAR_DECL.
+ (And don't worry about it being a TREE_LIST.)
+
+Tue Apr 5 13:26:42 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (YYDEBUG): Always define.
+ * lex.c (YYDEBUG): Likewise.
+
+Mon Apr 4 11:28:17 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * class.c (finish_struct): backup out the change below, put the
+ new change for the same purpose. The change below breaks code.
+
+ * class.c (finish_struct): if pure virtual, copy node and make
+ RTL point to abort, then put in virtual table.
+ * decl2.c (grok_function_iit): reinstate Mar 31 change.
+
+Sat Apr 2 03:12:58 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (build_new): pedwarn about newing const and volatile
+ types.
+
+ * tree.c (get_identifier_list): Only do the special handling
+ thing if we're dealing with the main variant of the record type.
+
+ * cvt.c (convert_to_reference): When converting between
+ compatible reference types, use the pointer conversion machinery.
+ Don't just blindly overwrite the old type.
+
+Fri Apr 1 17:14:42 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): When looking at global functions,
+ be sure to use instance_ptr for the first argument, not some version
+ of it that has been cast to a base class. Also do this before
+ comparing candidates.
+
+Thu Mar 31 19:50:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Constructors can be called for
+ const objects.
+
+Thu Mar 31 16:20:16 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * decl2.c (grok_func_init): do not abort as rtl for pur virtual
+ fucntions. They can be defined somewhere else.
+
+Sat Jan 23 23:23:26 1994 Stephen R. van den Berg (berg@pool.informatik.rwth-aachen.de)
+
+ * decl.c (init_decl_processing): Declare __builtin_return_address
+ and __builtin_frame_address for C++ as well.
+
+Thu Mar 31 12:35:49 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck2.c (store_init_value): Integral constant variables are
+ always constant, even when doing -fpic.
+
+Sat Jan 23 23:23:26 1994 Stephen R. van den Berg (berg@pool.informatik.rwth-aachen.de)
+
+ * decl.c (redeclaration_error_message): Pass the types to
+ comptypes.
+
+Wed Mar 30 21:29:25 1994 Mike Stump <mrs@cygnus.com>
+
+ Cures incorrect errors about pure virtuals in a class, when they
+ have been overridden in a derived class.
+
+ * search.c (get_abstract_virtuals): Reimplement.
+ * search.c (get_abstract_virtuals_1): New routine.
+
+Wed Mar 30 14:10:04 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (push_template_decls): Make the pushed level pseudo
+ global.
+
+ * parse.y (extdefs): Don't pop everything if the current binding
+ level is pseudo_global.
+
+ * decl.c (pop_everything): Stop on reaching a pseudo-global
+ binding level.
+
+ * cp-tree.h (DECL_FUNCTION_MEMBER_P): Change to more reliable test.
+
+ * decl.c (duplicate_decls): Only copy DECL_SOURCE_{FILE_LINE} if
+ the old decl actually had an initializer.
+
+ * {various}: Clean up gcc -W complaints.
+
+ * cp-tree.h (DECL_FUNCTION_MEMBER_P): Currently defined to be
+ (DECL_CONTEXT (NODE) != NULL_TREE).
+
+ * parse.y (lang_extdef): Call pop_everything if necessary.
+
+ * decl.c (pop_everything): New function for popping binding
+ levels left over after a syntax error.
+ (pushdecl): Use DECL_FUNCTION_MEMBER_P to decide whether or not
+ a function is a member.
+
+Wed Mar 30 14:20:50 1994 Mike Stump <mrs@cygnus.com>
+
+ Cures calling a more base base class function, when a more derived
+ base class member should be called in some MI situations.
+
+ * search.c (make_binfo): Use more the more specialized base
+ binfos from the binfo given as the second argument to make_binfo,
+ instead of the unspecialized ones from the TYPE_BINFO.
+ * class.c (finish_base_struct): Likewise, update callers.
+ * search.c (dfs_get_vbase_types): Likewise.
+ * tree.c (propagate_binfo_offsets, layout_vbasetypes): Likewise.
+ * decl.c (xref_tag): Use NULL_TREE instead of 0.
+ * lex.c (make_lang_type): Likewise.
+
+Wed Mar 30 14:10:04 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (pushdecl): If pushing a C-linkage function, only do a
+ push_overloaded_decl.
+ (duplicate_decls): Standard overloading does not shadow built-ins.
+
+Tue Mar 29 00:54:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (end_template_decl): Don't call push_overloaded_decl.
+
+ * init.c (do_friend): Don't call push_overloaded_decl.
+
+ * decl.c (pushdecl): Call push_overloaded_decl for functions and
+ function templates.
+ (duplicate_decls): functions and function templates are not
+ duplicates, but don't complain about calling this function to
+ compare them.
+ (push_overloaded_decl): Don't deal with linkage. Call
+ duplicate_decls.
+ (redeclaration_error_message): Deal with linkage.
+
+ * decl.c (start_function): If push_overloaded_decl returns an
+ older version of the function, deal with it.
+
+ * decl.c (start_function): Be sure only to push_overloaded_decl
+ for non-members.
+
+ * decl.c (grokfndecl): Put back clearing of DECL_CHAIN for
+ methods.
+ (start_function): Lose broken and redundant code for checking old
+ decl.
+
+ * init.c (add_friend): Give line numbers of both friend decls
+ when warning about re-friending.
+
+ * pt.c (tsubst): Use comptypes rather than == to compare the
+ types of the method as declared and as defined, since default
+ parameters may be different.
+
+ * call.c (build_method_call): Use brendan's candidate printing
+ routine.
+
+ * decl.c (start_method): Methods defined in the class body are
+ inline whether or not it's a template class.
+
+Mon Mar 28 16:39:26 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (initdcl0): Add "extern" to current_declspecs if
+ have_extern_spec && ! used_extern_spcec.
+
+ * tree.c (really_overloaded_fn): A fn with more than one
+ overload.
+
+ * pt.c (end_template_decl): Use really_overloaded_fn.
+
+ * decl.c (duplicate_decls): When smashing a decl into a previous
+ definition, keep the old file and line.
+ Don't deal with overloaded functions.
+ Lose old code for checking arg types of functions.
+ Check for overloaded C functions.
+ (pushdecl): Deal with overloaded functions.
+ (start_decl): Expect pushdecl to return an appropriate function decl.
+ (start_function): Likewise.
+ (push_overloaded_decl): Don't check for overloaded C functions.
+
+ * *.c: Stop using DECL_OVERLOADED, it being archaic.
+ TREE_OVERLOADED should probably go, too.
+
+Mon Mar 28 14:00:45 1994 Ron Guilmette <rfg@netcom.com>
+
+ * typeck.c (comp_target_types): Call comp_target_parms with
+ strict == 1.
+
+Sun Mar 27 00:07:45 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (empty_parms): Don't parse () as (...) in extern "C"
+ sections if we're compiling with -ansi or -pedantic.
+
+ * decl.c (decls_match): Don't treat (int) and (int&) as matching.
+
+ * decl2.c (grokfield): Don't pedwarn twice about initializing
+ field.
+
+ * decl.c (push_overloaded_decl): Warn about shadowing
+ constructor.
+ (redeclaration_error_message): Don't allow 'int a; int a;'
+
+ * cvt.c (build_up_reference): Only check for valid upcast if
+ LOOKUP_PROTECT is set, not just any flag.
+
+Fri Mar 25 01:22:31 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (check_newline): When we see a #pragma implementation,
+ also set it for the main input file.
+
+ * init.c (build_new): Convert array size argument to size_t.
+
+ * parse.y (primary): If we're doing a parenthesized type-id, call
+ groktypename before passing it to build_new.
+
+ * call.c (build_method_call): Deal properly with const and
+ volatile for instances of reference type.
+
+ * decl.c (store_return_init): Change 'if (pedantic) error' to 'if
+ (pedantic) pedwarn'.
+
+ * decl.c (grokdeclarator): Don't complain about putting `static'
+ and `inline' on template function decls.
+
+Thu Mar 24 23:18:19 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Preserve const & volatile on
+ `this'.
+
+Thu Mar 24 16:21:52 1994 Mike Stump <mrs@cygnus.com>
+
+ * init.c (build_new, build_vec_delete): Use global new and delete
+ for arrays.
+ * decl2.c (delete_sanity): Likewise.
+
+Thu Mar 24 02:10:46 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): If i is an lvalue,
+ (int &)i -> *(int*)&i, as per 5.2.8p9 of the latest WP.
+ (convert_force): Call convert_to_reference with LOOKUP_COMPLAIN.
+
+Wed Mar 23 17:45:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (duplicate_decls): Also propagate DECL_TEMPLATE_MEMBERS
+ and DECL_TEMPLATE_INSTANTIATIONS.
+
+ * init.c (build_new): Handle array typedefs properly.
+
+Wed Mar 23 18:23:33 1994 Mike Stump <mrs@cygnus.com>
+
+ 30th Cygnus<->FSF merge.
+
+Wed Mar 23 00:46:24 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (modify_vtable_entries): Avoid running off the end of the
+ virtuals list when processing a virtual destructor.
+ * class.c (get_vtable_entry): Likewise.
+
+Wed Mar 23 00:23:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (duplicate_decls): If two template decls don't match,
+ just return 0.
+
+Tue Mar 22 23:49:41 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (convert_for_assignment): Don't pedwarn about
+ converting function pointer to void *.
+
+Tue Mar 22 22:23:19 1994 Mike Stump <mrs@cygnus.com>
+
+ Major revamp of pointer to member functions. Cures major
+ nonfunctionality when used in casts, and MI situations.
+
+ * cvt.c (convert_force): Update call site of build_ptrmemfunc.
+ * typeck.c (convert_for_assignment): Likewise.
+ * typeck2.c (digest_init): Likewise.
+ * typeck2.c (process_init_constructor): Simplify by moving code into
+ digest_init.
+ * typeck2.c (digest_init): Do default_conversions on init value, if
+ we are processing pointer to member functions.
+ * class.c (get_vfield_offset): Now non-static. Convert bit offset
+ into byte offset.
+ * cp-tree.h (get_vfield_offset): Likewise.
+ * typeck.c (get_member_function_from_ptrfunc): Convert down to right
+ instance, before fetching vtable pointer.
+ * typeck.c (get_delta_difference): New routine.
+ * typeck.c (build_ptrmemfunc): Revamp to handle casting better, also
+ get vtable pointer out of right subobject.
+
+Tue Mar 22 17:56:48 1994 Mike Stump <mrs@cygnus.com>
+
+ * search.c (get_binfo): Return NULL instead of aborting, when
+ passed a UNION_TYPE.
+
+Tue Mar 22 12:44:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ These patches implement handling of redefinition/redeclaration of
+ templates.
+
+ * typeck.c (comptypes): Simplify. All TEMPLATE_TYPE_PARMs are
+ considered compatible.
+
+ * parse.y (template_def): Pass defn argument to end_template_decl.
+
+ * pt.c (end_template_decl): Add defn argument. Check for
+ redefinition. Simplify.
+
+ * error.c (OB_UNPUT): New macro, to remove mistakes.
+ (aggr_variety): Subroutine of dump_aggr_type.
+
+ * decl.c (decls_match): Support templates.
+ (duplicate_decls): No longer static. Don't try to lay out template
+ decls.
+ (pushdecl): Simplify.
+
+ * cp-tree.h (DECL_TEMPLATE_MEMBERS): Use DECL_SIZE instead of
+ DECL_INITIAL.
+
+Mon Mar 21 11:46:55 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * error.c (dump_decl): Support class template decls.
+ (dump_type): Don't adorn template type parms.
+
+ * decl.c (duplicate_decls): Save DECL_TEMPLATE_INFO from old decl
+ if it was a definition.
+ (redeclaration_error_message): Do the cp_error thang, and reject
+ redefinition of templates.
+
+Mon Mar 21 19:36:06 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (grokdeclarator): Set TREE_PUBLIC for METHOD_TYPE
+ in FIELD context, when appropriate. Also,
+ CLASSTYPE_INTERFACE_ONLY is irrelevant to setting TREE_PUBLIC.
+ Also, simplify check for bogus return specifiers.
+
+Mon Mar 21 11:46:55 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (after_type_declarator1): Expand type_quals.
+ (notype_declarator1): Likewise.
+ (absdcl1): Likewise.
+
+Sat Mar 19 01:05:17 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Treat class-local typedefs like static
+ members; i.e. 'typedef int f();' means that f is a function type,
+ not a method type.
+
+ * parse.y (decl): Change direct_* back to *.
+ (type_id): Change direct_abstract_declarator to absdcl.
+ (direct_declarator, direct_initdecls, direct_initdcl0): Remove again.
+
+Fri Mar 18 12:47:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ These two patches fix crashes on instantiating a template inside a
+ function with C linkage or containing labels.
+
+ * class.c (current_lang_stacksize): No longer static.
+
+ * decl.c (struct saved_scope): Add lang_base, lang_stack,
+ lang_name, lang_stacksize, and named_labels.
+ (push_to_top_level): Save them.
+ (pop_from_top_level): Restore them.
+
+ * gxxint.texi (Parser): Update.
+
+ These two patches finish moving the task of expr/declarator
+ ambiguity resolution from the lexer to the parser, and add one more
+ r/r conflict. START_DECLARATOR can now be nuked.
+
+ * parse.y (decl): Add "direct_" in typespec X rules.
+ (direct_declarator): New nonterminal for
+ direct_after_type_declarator and direct_notype_declarator.
+ (direct_initdecls): Like initdecls, but uses direct_initdcl0.
+ (direct_initdcl0): Like initdcl0, but uses direct_declarator.
+ (named_parm): Add typespec direct_declarator rule.
+
+ * spew.c (yylex): #if 0 out START_DECLARATOR insertion.
+
+ These two patches disable some excessive cleverness on the part of
+ g++; a non-class declaration always hides a class declaration in the
+ same scope, and g++ was trying to unhide it depending on the
+ enclosing expression.
+
+ * spew.c (arbitrate_lookup): #if 0 out.
+
+ * decl.c (lookup_name): Never call arbitrate_lookup.
+
+ * parse.y (complex_notype_declarator1): Add '*'
+ complex_notype_declarator1 and '&' complex_notype_declarator1 rules.
+
+ * parse.y (complex_direct_notype_declarator): Restore id_scope
+ see_typename TYPENAME rule, remove all other rules beginning with
+ those tokens.
+ (notype_unqualified_id): Add '~' see_typename IDENTIFIER rule.
+
+Thu Mar 17 17:30:01 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ These changes fix the compiler's handling of the functional cast/
+ object declaration ambiguities in section 6.8 of the ARM. They also
+ add 11 reduce/reduce conflicts. Sigh.
+
+ * parse.y: Add precedence decls for OPERATOR and '~'.
+ (notype_unqualified_id): New nonterminal, encompasses all of the
+ ANSI unqualified-id nonterminal except TYPENAMEs.
+ (expr_or_declarator): New nonterminal to delay parsing of code like
+ `int (*a)'.
+ (primary): Use notype_unqualified_id.
+ (decl): Add typespec initdecls ';' and typespec declarator ';'
+ rules.
+ (initdcl0): Deal with the above.
+ (complex_notype_declarator1): A notype_declarator that is not also
+ an expr_or_declarator.
+ (complex_direct_notype_declarator): A direct_notype_declarator that
+ doesn't conflict with expr_or_declarator. Use
+ notype_unqualified_id. Remove id_scope see_typename TYPENAME rule.
+ (functional_cast): New nonterminal, for the three functional cast
+ rules. So that they can be moved after
+ complex_direct_notype_declarator.
+ (see_typename): Don't accept type_quals any more.
+
+ * decl2.c (reparse_decl_as_expr): New function to deal with parse
+ nodes for code like `int (*a)++;'.
+ (reparse_decl_as_expr1): Recursive subroutine of the above.
+ (finish_decl_parsing): New function to deal with parse nodes for
+ code like `int (*a);'. See the difference?
+
+Thu Mar 17 12:16:10 1994 Mike Stump <mrs@cygnus.com>
+
+ These changes break binary compatibility in code with classes
+ that use virtual bases.
+
+ * search.c (dfs_get_vbase_types): Simplify and correct to make
+ sure virtual bases are initialized in dfs ordering.
+ * search.c (get_vbase_types): Simplify and make readable.
+
+Thu Mar 17 12:01:10 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y: s/ typename / type_id /g
+
+Wed Mar 16 17:42:52 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * parse.y (typespec): add SCOPE TYPENAME for global scoped
+ type. e.g. ::B x.
+
+ * decl.c (complete_array_type): fix a bug that in -pendantic
+ mode even there's no initializer, it will continue to build
+ default index.
+
+Wed Mar 16 17:43:07 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (direct_notype_declarator): Add PTYPENAME rule, remove
+ all of the scoped PTYPENAME rules.
+
+Wed Mar 16 16:39:02 1994 Mike Stump <mrs@cygnus.com>
+
+ * init.c (build_offset_ref): The value of A::typedef_name is
+ always the TYPE_DECL, and never an error.
+
+Tue Mar 15 20:02:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * search.c (get_base_distance_recursive): Two binfos can only
+ represent the same object if they are both via_virtual.
+
+ * class.c (finish_base_struct): Check vbases for ambiguity, too.
+
+ * search.c (get_vbase_types): Accept binfo argument, too.
+
+Tue Mar 15 19:22:05 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * decl.c (complete_array_type): complete TYPE_DOMAIN of the
+ initializer also, because back-end requires it.
+
+Tue Mar 15 15:33:31 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * error.c (dump_expr): Support member functions (which show up as
+ OFFSET_REFs).
+
+Mon Mar 14 16:24:36 1994 Mike Stump <mrs@cygnus.com>
+
+ * init.c (build_new): Set the return type of multidimensional
+ news correctly.
+
+Fri Mar 11 15:35:39 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * call.c (build_method_call): if basetype not equal to type
+ of the instance, use the type of the instance in building
+ destructor.
+
+Thu Mar 10 17:07:10 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * parse.y (direct_notype_declarator): add push_nested_type for
+ 'template_type SCOPED_NAME' rule.
+
+Tue Mar 8 00:19:58 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (parm): Add typed_declspec1 {absdcl, epsilon} rules.
+
+Sat Mar 5 04:47:48 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (regcast_or_absdcl): New nonterminal to implement late
+ reduction of constructs like `int ((int)(int)(int))'.
+ (cast_expr): Use it.
+ (sub_cast_expr): Everything that can come after a cast.
+ (typed_declspecs1): typed_declspecs that are not typed_typespecs.
+ (direct_after_type_declarator): Lose PAREN_STAR_PAREN rule.
+ (direct_abstract_declarator): Replace '(' parmlist ')' rule with
+ '(' complex_parmlist ')' and regcast_or_absdcl.
+ (parmlist): Split
+ (complex_parmlist): Parmlists that are not also typenames.
+ (parms_comma): Enabler.
+ (named_parm): A parm that is not also a typename. Use declarator
+ rather than dont_see_typename abs_or_notype_decl. Expand
+ typed_declspecs inline.
+ (abs_or_notype_decl): Lose.
+ (dont_see_typename): Comment out.
+ (bad_parm): Break out abs_or_notype_decl into two rules.
+
+Fri Mar 4 18:22:39 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (reparse_decl_as_casts): New function to change parse
+ nodes for `(int)(int)(int)' from "function taking int and returning
+ function taking int and returning function taking int" to "... cast
+ to int, cast to int, cast to int".
+
+ * decl2.c (reparse_decl_as_expr): Recursive function to change
+ parse nodes for `A()()' from "function returning function returning
+ A" to "A().operator()".
+
+ * parse.y (primary): Replace `typespec LEFT_RIGHT' rule with
+ `typespec fcast_or_absdcl' rule.
+ (fcast_or_absdcl): New nonterminal to implement late reduction of
+ constructs like `A()()()()'.
+ (typename): Replace `typespec absdcl1' rule with
+ `typespec direct_abstract_declarator' rule.
+ (direct_abstract_declarator): Replace `LEFT_RIGHT type_quals' rule
+ with `fcast_or_absdcl type_quals' rule.
+
+Fri Mar 4 16:18:03 1994 Mike Stump <mrs@cygnus.com>
+
+ * tree.c (lvalue_p): Improve OFFSET_REF handling, so that it
+ matches Section 5.5.
+
+Fri Mar 4 14:01:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * error.c (dump_type_prefix): Don't print basetype twice for
+ pmfs.
+
+Fri Mar 4 13:24:33 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (convert_arguments): Handle setHandler(A::handlerFn)
+ so that it is like setHandler(&A::handlerFn). Cures an `invalid
+ lvalue in unary `&''.
+
+Fri Mar 4 11:15:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * gxxint.texi (Copying Objects): New section discussing default
+ op= problems with virtual inheritance.
+
+ * decl2.c (grokoptypename): Just does grokdeclarator and
+ build_typename_overload, since the parser can't call grokdeclarator
+ directly.
+
+ * method.c (build_typename_overload): Set IDENTIFIER_GLOBAL_VALUE
+ and TREE_TYPE on generated identifiers.
+
+ * decl.c (grokdeclarator): Don't deal with TYPE_EXPRs anymore.
+
+ * parse.y (parm): Convert `const char *' to `__opPCc' here.
+
+ * error.c (dump_decl): Say sorry rather than my_friendly_aborting
+ if we can't figure out what to do.
+ (dump_type*): Likewise.
+
+ * typeck2.c (build_m_component_ref): 'component' is an expr, not
+ a decl. Also move the IS_AGGR_TYPE check after the stripping of
+ REFERENCE_TYPE.
+
+Fri Mar 4 04:46:05 1994 Mike Stump <mrs@cygnus.com>
+
+ * call.c (build_method_call): Handle b->setHandler(A::handlerFn)
+ so that it is like b->setHandler(&A::handlerFn). Cures an `invalid
+ lvalue in unary `&''.
+
+Thu Mar 3 12:38:15 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y: Add precedence specification for START_DECLARATOR.
+ (type_quals): Move before primary.
+ (typename): Move before typed_declspecs, add 'typespec absdcl1' rule.
+
+ * decl2.c (grokoptypename): Lose.
+
+ * decl.c (grokdeclarator): Parse TYPE_EXPRs in the initial scan,
+ rather than waiting until later.
+
+Wed Mar 2 14:12:23 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (unary_expr): Use 'typename' in 'new' rules, rather
+ than expanding it inline.
+ (typename): Expand empty option of (former) absdcl inline.
+ (abs_or_notype_decl): Likewise.
+ (absdcl): Lose empty rule.
+ (conversion_declarator): New nonterminal for 'typename' of 'operator
+ typename'.
+ (operator_name): Use it instead of absdcl.
+
+ * parse.y: Add precedence declarations for SCOPED_TYPENAME,
+ TYPEOF, and SIGOF.
+ (typed_declspecs): Accept typed_typespecs, rather than typespec
+ directly. Add rules with reserved_typespecquals.
+ (reserved_declspecs): Don't accept typespecqual_reserved at the
+ beginning of the list. The typed_declspecs rule will deal with this
+ omission.
+ (declmods): Accept nonempty_type_quals, rather than TYPE_QUAL
+ directly.
+
+ * parse.y (direct_notype_declarator,
+ direct_after_type_declarator, direct_abstract_declarator): Split up
+ the declarator1 nonterminals to match the draft standard and avoid
+ ambiguities.
+ (new_type_id, new_declarator, direct_new_declarator,
+ new_member_declarator): New nonterminals to implement the subset of
+ 'typename' allowed in new expressions.
+ (unary_expr): Use new_type_id instead of typename.
+ (after_type_declarator1, absdcl1): Fix semantics of member pointers.
+ (abs_member_declarator, after_type_member_declarator): Lose.
+
+ * parse.y (absdcl1): Don't require parens around
+ abs_member_declarator.
+ (abs_member_declarator): Lose see_typename from rules.
+ (after_type_member_declarator): Likewise.
+
+ * tree.c (get_identifier_list): New function, containing code
+ previously duplicated in get_decl_list and list_hash_lookup_or_cons.
+ (get_decl_list): Use it.
+ (list_hash_lookup_or_cons): Likewise.
+
+ * parse.y (typed_declspecs, declmods): It's not necessary to hash
+ the declspecs on class_obstack, so don't. This way typed_typespecs
+ can reduce to typed_declspecs.
+
+Wed Mar 2 14:29:18 1994 Jason Merrill <jason@cygnus.com>
+
+ * cvt.c (build_up_reference): If we aren't checking visibility,
+ also allow base->derived conversions.
+
+Mon Feb 28 15:14:29 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * typeck.c (build_c_cast): Remove bogus hack when converting
+ to a reference type.
+
+ * cp-tree.h (lang_decl::vbase_init_list, DECL_VBASE_INIT_LIST):
+ Removed, not used.
+ (lang_stype::methods, lang_decl::next_method): New fields.
+ (CLASSTYPE_METHODS, DECL_NEXT_METHOD): New macros.
+ * decl.c (duplicate_decls): Preserve DECL_NEXT_METHOD.
+
+ * cp-tree.h, decl2.c (flag_vtable_hack): New flag.
+ * decl2.c (finish_vtable_vardecl): If flag_vtable_hack,
+ and !CLASSTYPE_INTERFACE_KNOWN, try to use the presence of
+ a non-inline virtual function to control emitting of vtables.
+ * class.c (finish_struct): Build CLASSTYPE_METHODS list.
+ * search.c (build_vbase_vtables_init): Don't assemble_external
+ (yet) if flag_vtable_hack.
+ * class.c (build_vfn_ref): Likewise.
+
+Mon Feb 28 14:54:13 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (component_decl): Don't include "typed_declspecs
+ declarator ';'" speedup, since it breaks enums.
+
+Fri Feb 25 15:43:44 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * class.c (finish_struct): Minor optimization for building
+ fn_fields list.
+
+Fri Feb 25 15:23:42 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (start_function): Fix detection of function overloading.
+
+Thu Feb 24 22:26:19 1994 Mike Stump <mrs@cygnus.com>
+
+ * lex.c (check_newline): #pragma interface can take a string
+ argument, just like #pragma implementation. #pragma implementation
+ checks for garbage on the line, line #pragma interface does. Main
+ input files do not auto implement like named files, #pragma
+ implementation must be used explicitly.
+
+Thu Feb 24 17:09:01 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (components): Handle list of one again.
+ (notype_components): Likewise.
+ (after_type_declarator1): Take maybe_raises out again.
+
+ * gxxint.texi (Parser): Document additional r/r conflict.
+
+Wed Feb 23 14:42:55 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * gxxint.texi (Parser): Add node.
+
+ * Makefile.in (stamp-parse): Update expected conflict count.
+
+ * parse.y (various): Replace "declmods declarator" with "declmods
+ notype_declarator". The comment saying that "declmods declarator ';'"
+ corresponds to "int i;" was wrong; it corresponds to "const i;".
+ (component_decl): Add "typed_declspecs declarator ';'" rule; this
+ *does* correspond to "int i;". Change "declmods components" to
+ "declmods notype_components".
+ (components): Don't deal with a list of one anymore.
+ (notype_components): New nonterminal, corresponds to notype_declarator.
+ ({after_,no}type_component_decl{,0}): More new nonterminals.
+ ({after_,no}type_declarator): Fold in START_DECLARATOR token.
+ Eliminates four reduce/reduce conflicts.
+
+ (expr): Depend on nontrivial_exprlist instead of nonnull_exprlist.
+ (nontrivial_exprlist): New nonterminal: A list of at least two
+ expr_no_commas's.
+ (nonnull_exprlist): Depend on nontrival_exprlist.
+ Eliminates four reduce/reduce conflicts.
+
+ (named_class_head): Move intermediate code block into separate
+ nonterminal so that we can stick %prec EMPTY on it.
+
+ Add more %prec EMPTY's to eliminate remaining shift/reduce
+ conflicts.
+
+ (after_type_declarator): Add maybe_raises to fndecl rules.
+ (after_type_declarator_no_typename): Remove.
+ For correctness.
+
+ Document remaining reduce/reduce conflicts.
+
+Tue Feb 22 12:10:32 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * search.c (get_base_distance): Only bash BINFO_INHERITANCE_CHAIN
+ (TYPE_BINFO (type)) if we care about the path.
+
+ * tree.c (lvalue_p): A COND_EXPR is an lvalue if both of the
+ options are.
+
+Mon Feb 21 19:59:40 1994 Mike Stump <mrs@cygnus.com>
+
+ * Makefile.in (mostlyclean): lex.c is a source file, don't
+ remove.
+
+Sat Feb 19 01:27:14 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y: Eliminate 20 shift/reduce conflicts.
+
+Fri Feb 18 11:49:42 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (type_unification): Add subr argument; if set, it means
+ that we are calling ourselves recursively, so a partial match is OK.
+ (unify): Support pointers to methods and functions.
+ (tsubst): Support method pointers.
+ * decl.c (build_ptrmemfunc_type): No longer static, so that
+ tsubst can get at it.
+
+ * init.c (is_aggr_typedef): Pretend template type parms are
+ aggregates.
+ * decl2.c (build_push_scope): If cname refers to a template type
+ parm, just grin and nod.
+
+ * call.c (build_overload_call_real): Pass subr argument to
+ type_unification.
+ * pt.c (do_function_instantiation): Likewise.
+ * class.c (instantiate_type): Likewise.
+
+ * search.c (get_base_distance): If BINFO is a binfo, use it and
+ don't mess with its BINFO_INHERITANCE_CHAIN.
+
+ * cvt.c (convert_to_reference): Fix temporary generation.
+ If ambiguous, return error_mark_node.
+
+ * init.c (build_new): Put back some necessary code.
+
+Thu Feb 17 15:39:47 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (build_new): Deal with array types properly.
+
+ * search.c (get_binfo): Become a shell for get_base_distance.
+ (get_binfo_recursive): Lose.
+ (get_base_distance_recursive): Find the path to the via_virtual base
+ that provides the most access.
+ (get_base_distance): Likewise.
+
+ * parse.y (explicit_instantiation): Syntax is 'template class
+ A<int>', not 'template A<int>'.
+
+ * typeck.c (convert_for_initialization): Remove bogus warning.
+
+ * parse.y (datadef): Revert patch of Oct 27.
+
+Thu Feb 17 15:12:29 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * class.c (build_vfn_ref): Cast delta field to ptrdiff_type_node,
+ rather than integer_type_node. Does wonders for the Alpha.
+
+Thu Feb 17 13:36:21 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (build_ptrmemfunc_type): Make sure that the pmf type
+ goes onto the same obstack as its target type.
+
+Wed Feb 16 00:34:46 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): If converting via constructor
+ on local level, go back to build_cplus_new approach.
+
+ * tree.c (build_cplus_new): If with_cleanup_p, set cleanup slot
+ to error_mark_node to prevent expand_expr from building a cleanup
+ for this variable.
+
+ * lex.c (default_assign_ref_body): Return *this from the memcpy
+ version, too.
+
+ * decl.c (grok_reference_init): Just return if called with
+ error_mark_node, don't worry about initializing non-const reference
+ with temporary.
+
+ * cvt.c (convert_to_reference): Do the right thing for
+ non-aggregate reference conversions, pedwarn when generating a
+ non-const reference to a temporary.
+
+ * class.c (finish_struct): TYPE_HAS_COMPLEX_{INIT,ASSIGN}_REF and
+ TYPE_NEEDS_CONSTRUCTING all depend on TYPE_USES_VIRTUAL_BASECLASSES
+ again.
+
+Tue Feb 15 19:47:19 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grok_reference_init): Pawn off a lot of the work on
+ convert_to_reference. Generally do the right thing.
+
+ * cvt.c (convert_to_reference): Conform to the initial comment;
+ i.e. don't create temps if decl != error_mark_node. Handle
+ cleanups better for temps that do get created. Don't pretend
+ that we can use an 'A' to initialize a 'const double &' just by
+ tacking on a NOP_EXPR. Support LOOKUP_SPECULATIVELY.
+
+ * call.c (build_method_call): Set TREE_HAS_CONSTRUCTOR on
+ constructor calls.
+
+Mon Feb 14 14:50:17 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grok_reference_init): Make a temporary for initializing
+ const reference from constant expression.
+
+Mon Feb 14 11:31:31 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * cp-tree.h, decl.c (set_identifier_local_value): Deleted function.
+ * decl.c (pushdecl): Define decl in correct binding_level
+ (which isn't always the inner_binding_level).
+
+ * cvt.c (build_up_reference): Don't ever call expand_aggr_init.
+ It's ugly, and I don't think it's the right thing to do.
+
+ * cp-tree.h, class.c, decl.c, decl2.c, sp/search.c:
+ Remove NEW_CLASS_SCOPING, assuming it is always 1.
+ * decl.c (pop_decl_level): Removed; manually inlined.
+
+Sun Feb 13 19:04:56 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.h (candidate): Add basetypes field.
+
+ * call.c (build_method_call): Do access checking after choosing a
+ function, not before.
+
+ * Makefile.in (cvt.o, call.o, method.o): Depend on class.h.
+ (mostlyclean): Remove ../cc1plus.
+
+Fri Feb 11 11:52:26 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Don't allow adjusting access to a field
+ of a base class if a local field has the same name.
+
+ * error.c (dump_type_prefix): Output basetype for METHOD_TYPEs.
+
+hu Jan 13 17:55:51 EST 1994 Gnanasekaran Swaminathan <gs4t@virginia.edu>
+
+ * cp-tree.h (DESTRUCTOR_NAME_P): do not confuse AUTO_TEMP names
+ with destructor names when either NO_DOLLAR_IN_LABEL or
+ NO_DOT_IN_LABEL are not defined.
+
+ Now `template <class T, T f(T&), const T*> class A {...}' works.
+
+ * pt.c (grok_template_type): substitute template parm types
+ with actual types in complex type as well.
+ (coerce_template_parms): update the grok_template_type ()
+ function call.
+
+ * pt.c (tsubst): Traverse method list using DECL_CHAIN.
+
+ * decl.c (grok_op_properties): Allow operator++/-- to have
+ default arguments.
+
+ * typeck2.c (store_init_value): Don't abort when called to
+ initialize a type that needs constructing with a CONSTRUCTOR.
+
+ * init.c (expand_aggr_init_1, CONSTRUCTOR case): If
+ store_init_value fails, build and expand an INIT_EXPR. If
+ store_init_value succeeds, call expand_decl_init.
+
+Fri Feb 11 02:49:23 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (build_vbase_path): Use complete_type_p instead of
+ resolves_to_fixed_type_p to determine if the virtual bases are in
+ their right place for the type of expr. Cures problem of thinking a
+ virtual base class is one place, when it is in fact someplace else.
+
+Fri Feb 11 00:26:46 1994 Mike Stump <mrs@cygnus.com>
+
+ * init.c (resolve_offset_ref): Make sure we first convert to
+ intermediate type, if given, when dealing with members off `this'.
+ Solves an incorrrect `type `foo' is not a base type for type
+ `multiple'' when it is infact, a base type.
+
+Thu Feb 10 21:49:35 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (modify_other_vtable_entries): Use get_binfo, instead
+ of binfo_value. Solves problem with compiler giving a `base class
+ `B' ambiguous in binfo_value (compiler error)' on complex MI
+ herarchies, when a virtual function is first defied in a virtual
+ base class.
+
+Thu Feb 10 17:19:32 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (build_vbase_path): Don't complain about ambiguous
+ intermediate conversion when converting down to a virtual base
+ class, even if they might seem to be ambiguous.
+
+Thu Feb 10 12:18:26 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck2.c (build_functional_cast): #if 0 out constructor
+ inheritance code, improve error messages.
+
+ * class.c (finish_base_struct): Complain about base with only
+ non-default constructors in derived class with no constructors.
+
+ * decl.c (grokdeclarator): Fix detection of virtual new/delete.
+
+Wed Feb 9 22:02:32 1994 Mike Stump <mrs@cygnus.com>
+
+ * search.c (build_mi_virtuals, add_mi_virtuals,
+ report_ambiguous_mi_virtuals): Removed unneeded code.
+ * class.c (finish_struct_bits): Likewise.
+
+Wed Feb 9 11:27:17 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (end_template_instantiation): Push decl before
+ pop_from_top_level.
+
+ * typeck2.c (build_m_component_ref): Make sure datum is of
+ aggregate type.
+
+ * init.c (get_type_value): New function, returns
+ IDENTIFIER_TYPE_VALUE or IDENTIFIER_CLASS_TYPE_VALUE or NULL_TREE.
+
+ * call.c (build_method_call): Don't die on call to destructor for
+ non-type.
+
+ * decl.c (grokdeclarator): Complain about virtual op new and op
+ delete, make static virtuals unvirtual instead of unstatic.
+
+ * typeck.c (build_c_cast): Also call default_conversion on
+ methods.
+
+ * decl.c (grokdeclarator): Don't complain about anonymous
+ bitfields.
+
+ * parse.y (simple_stmt, for loops): Move the continue point after
+ the cleanups.
+
+ * class.c (finish_struct): Fix setting of
+ TYPE_HAS_COMPLEX_INIT_REF.
+
+Tue Feb 8 13:21:40 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (build_new): Deal with `new double (1)'.
+
+ * class.c (finish_struct): TYPE_HAS_COMPLEX_*_REF are supersets of
+ TYPE_HAS_REAL_*_REF, but TYPE_HAS_COMPLEX_INIT_REF is independent of
+ TYPE_NEEDS_CONSTRUCTING.
+
+ * decl.c (duplicate_decls): Propagate access decls.
+
+ * typeck2.c (process_init_constructor): Accept empty_init_node
+ for initializing unions.
+
+ * class.c, lex.c, cp-tree.h: Use
+ TYPE_HAS_COMPLEX_ASSIGN_REF where TYPE_HAS_REAL_ASSIGN_REF was used
+ before, use TYPE_HAS_COMPLEX_INIT_REF for TYPE_NEEDS_CONSTRUCTING in
+ some places.
+
+ * decl.c (finish_decl): Don't complain about uninitialized const
+ if it was initialized before.
+
+Mon Feb 7 18:12:34 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (default_assign_ref_body): Don't deal with vbases for
+ now.
+
+ * decl.c (finish_decl): Fix reversed logic for objects and other
+ things that need to be constructed but have no initializer.
+
+ * class.c (finish_struct): Don't set TYPE_HAS_* flags that are
+ set by grok_op_properties or finish_decl.
+
+ * decl.c: Don't warn about extern redeclared inline unless
+ -Wextern-inline is given.
+ * decl2.c (lang_decode_option): Likewise.
+ * cp-tree.h: Likewise.
+
+Mon Feb 7 17:29:24 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (pushdecl_with_scope): Fix thinko. Add forward
+ declaration.
+
+ * decl.c (pushdecl_with_scope): New function.
+ * decl.c (pushdecl_top_level): Use new function.
+ * decl.c (pushtag): Initialize newdecl.
+ * decl.c (pushtag): Push new type decl into correct scope.
+
+Mon Feb 7 14:42:03 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c, cvt.c, init.c, search.c, cp-tree.h:
+ Eradicate LOOKUP_PROTECTED_OK.
+
+Mon Feb 7 13:57:19 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (pushtag, xref_tag), cp-tree.h: Add extra parameter
+ 'globalize' to signify implicit declarations.
+ * decl.c (globalize_nested_type, maybe_globalize_type): Removed.
+ * decl.c (set_identifier_type_value_with_scope): New function.
+ * decl.c (set_identifier_local_value): Simplify.
+ * spew.c (yylex, do_addr): Modify to return a _DEFN if a
+ forward declaration (followed by ';' and not preceded by 'friend').
+ * class.c, decl.c, except.c, init.c, parse.y,
+ pt.c, search.c: Add new argument to calls to xref_tag and
+ pushtag.
+
+Mon Feb 7 00:22:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.h (ACCESSIBLY_UNIQUELY_DERIVED_P): New macro, means what
+ ACCESSIBLY_DERIVED_FROM_P meant before.
+ (ACCESSIBLY_DERIVED_FROM_P): Now disregards ambiguity.
+
+ * cvt.c (build_up_reference): Call get_binfo with PROTECT == 1.
+
+ * search.c (get_base_distance_recursive): Members and friends of
+ a class X can implicitly convert an X* to a pointer to a private or
+ protected immediate base class of X.
+ (get_binfo_recursive): Likewise.
+ (get_base_distance): Ignore ambiguity if PROTECT < 0.
+ (get_binfo): Lose multiple values of PROTECT.
+ (compute_access): Protected is OK if the start of the
+ search is an accessible base class of current_class_type.
+
+ * method.c (build_opfncall): Do check access on operator new here.
+
+ * decl.c (finish_function): Don't check access on operator new
+ here.
+
+Sun Feb 6 14:06:58 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (xref_tag): The base of a derived struct is NOT always
+ public. Duh.
+
+ * pt.c (do_explicit_instantiation): New function, called from
+ parser to do explicit function instantiation.
+ (type_unification): Allow the args list to be terminated with
+ void_list_node.
+ (do_pending_expansions): Look at i->interface for non-member
+ templates.
+
+ * parse.y (datadef): Move explicit_instantiation here.
+ (structsp): From here.
+ (datadef): Complain about `int;'.
+
+Sun Feb 6 12:33:18 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * pt.c (end_template_instantiation), cp-tree.h: Remove unused
+ second parameter, and simplify first from a TREE_LIST where
+ we only care about its TREE_VALUE to just the value (an IDENTIFIER).
+ * pt.c (instantiate_member_templates): Simplify argument list
+ from a TREE_LIST to just an IDENTIFIER.
+ * lex.c (yyprint): PRE_PARSED_CLASS_DECL is now just an IDENTIFIER.
+ * parse.y (template_instantiate_once): Simplify accordingly.
+ * decl.c (inner_binding_level): New. Use various places to
+ simplify.
+
+Sun Feb 6 02:49:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck2.c (build_functional_cast): int() -> int(0).
+
+Sat Feb 5 00:53:21 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Don't do a bitwise copy for op= if the
+ class has a virtual function table.
+
+ * typeck.c (convert_for_initialization): Restore warnings about
+ not using defined op=. Should really be my_friendly_aborts, I
+ s'pose.
+
+Fri Feb 4 14:21:00 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Tidy up conditions for doing bitwise
+ copies of objects.
+
+ * decl.c (build_default_constructor): #if 0 out.
+
+ * *: Eradicate TYPE_GETS_{ASSIGNMENT,ASSIGN_REF,CONST_ASSIGN_REF,
+ CONST_INIT_REF}, TYPE_HAS_REAL_CONSTRUCTOR.
+
+ * decl.c (grokdeclarator): Don't return void_type_node for
+ friends being defined here.
+
+ * init.c (perform_member_init): Only do the init if it's useful.
+
+ * lex.c (default_copy_constructor_body): If we don't need to do
+ memberwise init, just call __builtin_memcpy.
+ (default_assign_ref_body): Likewise.
+
+ * decl.c (grokdeclarator): If friendp && virtualp, friendp = 0.
+
+Fri Feb 4 13:02:56 1994 Mike Stump <mrs@cygnus.com>
+
+ * lex.c (reinit_parse_for_method, cons_up_default_function):
+ Don't give warn_if_unknown_interface warning when it came from a
+ system header file.
+ * pt.c (end_template_decl, instantiate_template): Likewise.
+ * decl.c (start_decl): Likewise.
+
+Fri Feb 4 00:41:21 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't try to set TYPE_WAS_ANONYMOUS on
+ enums.
+
+ * decl2.c (constructor_name_full): Use IS_AGGR_TYPE_CODE instead of
+ IS_AGGR_TYPE, since we don't know it's a type.
+
+Thu Feb 3 11:36:46 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't complain about anonymous unions.
+
+ * cp-tree.h (TYPE_WAS_ANONYMOUS): This struct was originally
+ anonymous, but had a name given to it by a typedef.
+
+ * decl.c (grokdeclarator): When renaming an anonymous struct, set
+ TYPE_WAS_ANONYMOUS.
+
+ * decl2.c (constructor_name_full): Use TYPE_WAS_ANONYMOUS.
+
+ * cp-tree.h (DECL_UNDEFINED_FRIENDS): #if 0 out.
+
+ * init.c (xref_friend): Don't set up DECL_UNDEFINED_FRIENDS.
+ (embrace_waiting_friends): Don't use DECL_UNDEFINED_FRIENDS.
+
+ * decl.c (grokdeclarator): Set TYPE_NESTED_NAME properly on nested
+ anonymous structs that get typedef'd.
+
+ * decl.c (grokdeclarator): Always return void_type_node for
+ friends.
+
+ * error.c (dump_function_decl): Don't use DECL_CLASS_CONTEXT for
+ friends.
+ (dump_function_decl): Don't print out default args for
+ a function used in an expression.
+
+ * decl.c (grokdeclarator): Give error on abstract declarator used
+ in an invalid context (i.e. `void (*)();').
+
+ * error.c (cp_line_of): Support _TYPE nodes.
+ (cp_file_of): Likewise.
+
+ * cvt.c (build_up_reference): Don't abort if passed a SAVE_EXPR;
+ it can happen for the RHS of an assignment stmt where the LHS is
+ a COND_EXPR.
+
+ * init.c (expand_aggr_init_1): Deal with bracketed initializer
+ lists properly.
+
+ * class.c (finish_struct): Deal with enumerators and typedefs
+ again.
+
+Wed Feb 2 11:30:22 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Tidy up loop over fields.
+
+ * errfn.c (cp_thing): Don't advance twice after a format.
+
+ * class.c (finish_struct): Complain about needing a constructor
+ if a member has only non-default constructors, and don't try to
+ generate a default constructor.
+
+ * decl.c (finish_decl): Also do the constructor thing if
+ TYPE_NEEDS_CONSTRUCTING is set (for arrays).
+
+ * search.c (unuse_fields): New function: mark all fields in this
+ type unused.
+ (dfs_unuse_fields): Helper function.
+
+ * class.c (pushclass): If the new class is the same as the old
+ class, still unuse the fields.
+ (unuse_fields): Move to search.c.
+
+ * decl.c (grok_op_properties): Add friendp argument.
+ (grokfndecl): Pass it.
+ (start_method): Likewise.
+
+ * decl2.c (delete_sanity): Add use_global_delete parameter to catch
+ ::delete calls.
+
+ * parse.y (unary_expr): Pass new parameter to delete_sanity.
+
+ * lex.c (default_copy_constructor_body): Don't choke if the union
+ has no fields.
+ (default_assign_ref_body): Likewise.
+
+ * call.c (compute_conversion_costs_ansi): Do the right thing for
+ ellipsis matches.
+
+ * decl.c (push_to_top_level): Optimize.
+
+ * decl.c (start_function): Look for the lexical scope of a friend
+ in DECL_CLASS_CONTEXT.
+
+ * init.c (do_friend): Set DECL_CLASS_CONTEXT on global friends.
+
+Tue Feb 1 15:59:24 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.h (TREE_GETS_PLACED_NEW): New macro.
+
+ * init.c (init_init_processing): Don't assign BIN/BID to the
+ IDENTIFIER_GLOBAL_VALUEs of their respective operators.
+ (build_new): Check TREE_GETS_PLACED_NEW.
+
+ * decl.c (grok_op_properties): Don't set TREE_GETS_NEW for a decl of
+ op new with placement, set TREE_GETS_PLACED_NEW.
+
+ * cp-tree.h (ANON_UNION_P): New macro. Applies to decls.
+
+ * class.c (finish_struct): Don't treat anonymous unions like
+ other aggregate members. Do synthesize methods for unions without
+ a name, since they may or may not be "anonymous unions".
+
+ * decl2.c (grok_x_components): Wipe out memory of synthesized methods
+ in anonymous unions.
+
+ * lex.c (default_copy_constructor_body): Support unions.
+ (default_assign_ref_body): Likewise.
+
+Mon Jan 31 12:07:30 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.h: Fix documentation of LOOKUP_GLOBAL, add prototypes.
+
+ * error.c (args_as_string): New function (%A), like type_as_string
+ except NULL_TREE -> "..."
+
+ * call.c (build_overload_call_real): Fix for new overloading.
+
+ * decl.c (grok_op_properties): Set all of the TYPE_OVERLOADS_* flags
+ here.
+
+ * parse.y (operator_name): Instead of here.
+
+ * typeck2.c (build_functional_cast): Treat a TREE_LIST as a list
+ of functions.
+
+ * call.c (build_overload_call_real): Support LOOKUP_SPECULATIVELY.
+
+ * method.c (build_opfncall): Don't need to massage return value
+ any more, call build_overload_call with all flags.
+
+ * typeck.c (build_x_binary_op): Put back speculative call to
+ build_opfncall.
+ (build_x_unary_op): Likewise.
+ (build_x_conditional_expr): Likewise.
+
+Mon Jan 31 10:00:30 1994 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (build_type_conversion_1): Change call to pedwarn into
+ warning, and conditionalize upon warn_cast_qual.
+
+Fri Jan 28 11:48:15 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * search.c (lookup_field): If xbasetype is a binfo, copy it to
+ avoid clobbering its inheritance info.
+
+ * call.c (build_method_call): Don't overwrite basetype_path with
+ TYPE_BINFO (inst_ptr_basetype) if they have the same type.
+
+ * search.c (compute_access): Fix handling of protected inheritance
+ and friendship with the enclosing class.
+
+ * typeck2.c (store_init_value): Allow passing of TREE_CHAIN for
+ initialization of arbitrary variable.
+
+ * typeck2.c (build_functional_cast): Only try calling a method if
+ one exists.
+
+ * decl.c (grokdeclarator): Move handling of constructor syntax
+ initialization into first loop for generality.
+ (parmlist_is_random): Lose.
+
+ * lex.c (cons_up_default_function): Set TREE_PARMLIST on arguments
+ to default function.
+
+Thu Jan 27 19:26:51 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokparms): Abort if we get called with something we don't
+ expect.
+
+Thu Jan 27 17:37:25 1994 Mike Stump <mrs@cygnus.com>
+
+ * call.c (build_overload_call_real): Change argument complain to
+ flags to match style of rest of code. Pass it down to
+ build_function_call_real as necessary.
+ * call.c (build_overload_call, build_overload_call_maybe): Change
+ argument complain to flags to match style of rest of code.
+ * cp-tree.h (build_function_call_real): Added fourth flags
+ argument.
+ * cvt.c (convert_to_reference): Only give warning messages, if
+ LOOKUP_COMPLAIN is set.
+ * typeck.c (build_x_function_call): Change simple complain
+ argument to build_overload_call_maybe and build_overload_call, to
+ LOOKUP_COMPLAIN to match style of rest of code.
+ * typeck2.c (build_functional_cast): Likewise.
+ * typeck.c (build_function_call_real): Add flags, so that we can
+ not complain, if we don't want to complain. Complain about
+ arguments, if we are complaining, otherwise don't.
+ * typeck.c (build_function_call, build_function_call_maybe):
+ Stick in flags argument.
+ * typeck.c (build_x_binary_op, build_x_unary_op,
+ build_x_conditional_expr, build_x_compound_expr): Follow style of
+ build_x_indirect_ref, as it is more correct and more common.
+
+Thu Jan 27 14:36:20 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Don't check for being called with
+ a pointer.
+
+ * decl2.c (finish_file): Don't play with DECL_CLASS_CONTEXT for the
+ static initializer function.
+
+ * init.c (build_member_call): Use convert_force here, too.
+
+ * search.c (compute_access): Only treat static members specially
+ if they are referenced directly.
+
+Wed Jan 26 18:28:14 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * gxxint.texi (Access Control): New node.
+
+ * search.c (current_scope): New function; returns whichever of
+ current_class_type and current_function_decl is the most nested.
+ (compute_access): Total overhaul to make it clearer and more
+ correct. Don't use the cache for now; in the only situation where
+ it was used before, it gained nothing. This frees up three of the
+ DECL_LANG_FLAGs for possible other use!
+
+ * cp-tree.h: #if 0 out DECL_PUBLIC & friends.
+
+ * typeck.c (build_component_ref_1): Don't check DECL_PUBLIC.
+
+ * call.c (build_method_call): Use convert_force to cast `this' --
+ rely on the access checking for the method itself.
+
+ * init.c (is_friend): Do the nesting thing, handle types. I am
+ my own friend.
+ (is_friend_type): Become a shell for is_friend.
+ (add_friend): Never stick in ctype.
+ Why are the friendship functions in init.c, anyway?
+
+Wed Jan 26 17:50:00 1994 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (build_type_conversion_1): Don't conditionalize call to
+ pedwarn upon pedantic.
+
+Wed Jan 26 17:20:46 1994 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (convert_to_reference): Add 8.4.3 checking so that one
+ gets a warning if one tries to initialize a non-const & from a
+ non-lvalue.
+ * cvt.c (convert_to_reference): Use %P format for argument
+ numbers in warnings.
+
+Wed Jan 26 14:35:06 1994 Mike Stump <mrs@cygnus.com>
+
+ * init.c (build_delete): Follow style in call.c to construct the
+ virtual call to the desctructor, as that code is right. Fixes a
+ problem of the compiler saying a pointer conversion is ambiguous.
+
+Wed Jan 26 11:28:14 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.h (VTABLE_NAME_P): Change other occurrence of
+ VTABLE_NAME_FORMAT to VTABLE_NAME.
+
+ * *: s/visibility/access/g
+
+Tue Jan 25 18:39:12 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_modify_expr): Don't smash references if INIT_EXPR.
+
+Tue Jan 25 13:54:29 1994 Mike Stump <mrs@cygnus.com>
+
+ * init.c (build_delete): Back out Jan 17th & 18th pacthes, as
+ they break libg++.
+
+Tue Jan 25 13:11:45 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (duplicate_decls): Fix pointer arithmetic.
+
+Mon Jan 24 15:50:06 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp-* changes propagated from c-* changes in 940114 snapshot ]
+ * cp-parse.y (maybe_attribute): Allow multiple __attribute__
+ clauses on a declaration.
+
+Mon Jan 24 17:06:23 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Do synthesize methods for anon
+ structs, just not unions.
+
+Mon Jan 24 13:50:13 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * decl.c (xref_tag): handle anonymous nested type.
+ * decl.c (globalize_nested_type): add no globalize bit check.
+ * spew.c (hack_more_ids) : templated nested decl not push top
+ level.
+
+ * parse.y : get rid of 'goto do_components'. It is much better
+ for debugging.
+
+ * decl.c (is_anon_name): get rid of the function and use the
+ macro ANON_AGGRNAME_P.
+ * pt.c : ditto.
+
+Fri Jan 21 14:06:02 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Don't synthesize any methods for
+ anonymous structs/unions.
+
+ * typeck.c (build_modify_expr): Don't treat pmf's as class objects.
+
+Thu Jan 20 18:56:46 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * method.c (build_opfncall): Call build_indirect_ref on
+ synthesized instance for operator delete.
+
+ * pt.c (type_unification): Don't abort if called with a list of
+ types in ARGS.
+
+ * class.c (instantiate_type): Deal with function templates.
+
+Thu Jan 20 16:55:35 1994 Jim Wilson <wilson@sphagnum.cygnus.com>
+
+ * Makefile.in (CC): Default to cc not gcc.
+
+Thu Jan 20 13:47:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_modify_expr): Call constructor if appropriate.
+
+ * decl.c (push_to_top_level): Clear out class-level bindings cache.
+
+Wed Jan 19 13:51:22 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (resolve_scope_to_name): Work recursively (previously only
+ looked down one level).
+
+ * lex.c (do_pending_inlines): If we're still dealing with the last
+ batch of inlines, don't start working on a new one.
+
+ * Makefile.in (stamp-parse): Update conflict count.
+ (TAGS): Fix.
+
+ * parse.y (explicit_instantiation): New rule; implements
+ 'template A<int>' syntax (though not 'template foo(int)' yet).
+ (structsp): Add explicit_instantiation.
+
+Tue Jan 18 13:53:05 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct, etc.): Simplify decision to synthesize
+ a destructor.
+
+ * call.c, class.c, cp-tree.h, decl.c, init.c,
+ ptree.c, search.c, typeck.c, typeck2.c: Nuke
+ TYPE_NEEDS_CONSTRUCTOR (change all calls to TYPE_NEEDS_CONSTRUCTING).
+ * init.c (expand_aggr_init_1): Don't try non-constructor methods
+ of initializing objects.
+ (build_new): Don't try other methods if the constructor lookup fails.
+
+ * class.c (finish_base_struct): Set cant_have_default_ctor and
+ cant_synth_copy_ctor properly.
+ (finish_struct): Likewise.
+
+Mon Jan 17 13:58:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_modify_expr_1): #if 0 out again.
+ (build_modify_expr): #if 0 out memberwise init code again.
+
+ * lex.c (default_copy_constructor_body): Be const-correct.
+ (default_assign_ref_body): Likewise.
+
+ * init.c (perform_member_init): Use TYPE_HAS_CONSTRUCTOR to decide
+ whether or not to use it, rather than TYPE_NEEDS_CONSTRUCTING.
+ (expand_aggr_init): Disable silent conversion from initializer list
+ to list of args for a constructor.
+
+ * class.c (base_info): Lose needs_default_ctor.
+ (finish_base_struct): Likewise.
+ (finish_struct): Likewise.
+
+ * decl.c (init_decl_processing): Don't turn off flag_default_inline
+ just because flag_no_inline is on.
+ (finish_decl): Use TYPE_HAS_CONSTRUCTOR to decide to use
+ constructor.
+
+ * class.c (finish_struct): Synthesize default ctor whenever
+ allowed.
+
+ * Makefile.in (TAGS): Don't try to run etags on cp-parse.y.
+
+Sat Jan 15 18:34:33 1994 Mike Stump <mrs@cygnus.com>
+
+ * Makefile.in, configure: Handle the C++ front-end in a
+ subdirectory.
+ * cp-*: Move C++ front-end to cp/*.
+
+Fri Jan 14 14:09:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-typeck.c (build_function_call_real): Modify to match other
+ instances of taking the address of the function.
+
+ * cp-class.c (finish_struct): Set TYPE_HAS_REAL_CONSTRUCTOR to 1 if
+ there are non-synthesized constructors.
+ Only set TYPE_NEEDS_CONSTRUCTOR if TYPE_HAS_REAL_CONSTRUCTOR.
+ Always generate copy constructor if possible.
+
+ * cp-tree.h (lang_type): Add has_real_constructor bitfield.
+ (TYPE_HAS_REAL_CONSTRUCTOR): Define.
+
+ * cp-lex.c (default_copy_constructor_body): Use init syntax
+ for all bases.
+
+ * cp-type2.c (store_init_value): Only give error for initializer list
+ if TYPE_HAS_REAL_CONSTRUCTOR.
+
+Thu Jan 13 15:38:29 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.h (DECL_SYNTHESIZED): Add defn.
+ (lang_decl): Add synthesized bitfield to decl_flags.
+
+ * cp-lex.c (cons_up_default_function): Use DECL_SYNTHESIZED to mark
+ artificial methods, rather than a line # of 0.
+
+Fri Jan 14 18:25:29 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * cp-decl (xref_tag): fix a bug in conflict type.
+ * cp-parse.y : add SCOPED_NAME for uninstantiated template nested
+ type reference.
+ * cp-spew.c (yylex) : generated SCOPED_NAME token.
+ * cp-lex.c (yyprint): handle SCOPED_NAME.
+
+Fri Jan 14 17:00:29 1994 Mike Stump <mrs@cygnus.com>
+
+ * cp-decl.c (pushdecl): Revert patch from Jan 11 19:33:03, as it is
+ not right.
+
+Thu Jan 13 14:00:35 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * cp-decl2.c (grok_x_components): fix a bug that enum type does not
+ have type_flags.
+
+Thu Jan 13 11:39:34 1994 Mike Stump <mrs@cygnus.com>
+
+ Ensure that all vtable pointers are initialized with all the right
+ values.
+
+ * cp-class.c (is_normal): Changed to reflect new meaning of
+ CLASSTYPE_VFIELD_PARENT.
+ * cp-class.c (maybe_fixup_vptrs): Use of
+ CLASSTYPE_NEEDS_VIRTUAL_REINIT here is misguided. Use
+ BINFO_MODIFIED instead.
+ * cp-class.c (finish_struct): Changed to reflect new meaning of
+ CLASSTYPE_VFIELD_PARENT.
+ * cp-decl.c (get_binfo_from_vfield): Removed, unneeded now.
+ * cp-decl.c (finish_function): Use init_vtbl_ptrs, instead of open
+ coding it here.
+ * cp-init.c (init_vfields): Changed name to init_vtbl_ptrs, and
+ re-implement.
+ * cp-init.c (emit_base_init): Use new name init_vtbl_ptrs.
+ * cp-tree.h (vfield_parent): Changed to integer.
+ * cp-tree.h (CLASSTYPE_VFIELD_PARENT): Changed docs to reflect new
+ meaning.
+ * cp-tree.h (init_vtbl_ptrs): Added init_vtbl_ptrs.
+
+Wed Jan 12 18:24:16 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * cp-decl.c (xref_tag): re-implement globalize nested type.
+ * cp-decl2.c (grok_x_components): ditto.
+ * cp-parse.y: ditto.
+ * cp-tree.h (lang_type): add no_globalize bit in type_flags.
+
+Wed Jan 12 14:08:09 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c (grokdeclarator): Don't set TREE_PUBLIC on friend
+ decls with a definition attached.
+
+ * cp-typeck.c (build_modify_expr): Undo previous change in the case
+ of INIT_EXPRs.
+
+Tue Jan 11 19:33:03 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-typeck.c (build_modify_expr): Replace code for generating
+ assignment semantics for classes with an error.
+ (build_modify_expr_1): #if 0 out.
+
+ * cp-decl.c (pushdecl): Patch bogus design of pushdecl
+ behavior for overloaded functions (it doesn't push anything).
+
+ * cp-class.c (finish_struct): When generating default op=,
+ set TYPE_HAS_ASSIGNMENT.
+
+Mon Jan 10 18:48:06 1994 Mike Stump <mrs@cygnus.com>
+
+ * cp-cvt.c (convert): Make {double, clashing enum} -> enum
+ invalid.
+ * cp-typeck.c (convert_for_assignment): Simplify.
+ * cp-decl2.c (warn_enum_clash): Removed.
+ * invoke.texi (-Wenum-clash): Removed.
+ * toplev.c (-Wenum-clash): Removed.
+
+Mon Jan 10 17:48:37 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * cp-decl.c (finish_decl): fix incorrect popclass call.
+
+ * cp-decl.c (is_anon_name): new function, check whether the name
+ is anonymous name generated by compiler.
+ * cp-decl.c (grokdeclarator): allow nested SCOPE_REF
+ * cp-spew.c (hack_more_ids): handle nested type in template.
+ * cp-parse.y : handle nested type reference in uninstantiated
+ template.
+ * cp-call.c (build_method_call): handle uninstantiated template
+ case.
+ * cp-pt.c (search_nested_type_in_tmpl): new function, search nested
+ type in template.
+ * cp-pt.c (lookup_nested_type_by_name): new function, lookup nested
+ type by name.
+ * cp-pt.c (tsubst): handle nested type search by name.
+
+Mon Jan 10 14:32:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-init.c (build_member_call): Propagate qualifiers to new type.
+
+ * cp-call.c (build_method_call): Count functions the new way.
+
+Fri Jan 7 19:03:26 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c (pushtag): Set DECL_ASSEMBLER_NAME for nested classes,
+ too.
+
+Tue Jan 4 16:45:51 1994 Kung Hsu <kung@cirdan.cygnus.com>
+
+ * cp-parse.y: change to handle whether to globalize nested class.
+ * cp-decl.c(xref_tag, maybe_globalize_type): Likewise.
+
+Mon Jan 3 22:22:32 1994 Gerald Baumgartner <gb@cygnus.com>
+
+ * Makefile.in cp-call.c cp-class.c cp-cvt.c cp-decl.c cp-decl2.c
+ cp-error.c cp-init.c cp-lex.c cp-lex.h cp-method.c cp-parse.y
+ cp-spew.c cp-tree.c cp-tree.h cp-type2.c cp-typeck.c cp-xref.c
+ gplus.gperf toplev.c: Incorporated C++ signature extension.
+ * cp-sig.c: New file, contains most of signature processing.
+ * cp-hash.h: Regenerated from gplus.gperf.
+
+ * gcc.1 g++.1: Added explanation for the `-fhandle-signatures'
+ and `-fno-handle-signatures' command line flags.
+
+ * gcc.texi: Changed the last-modification date.
+ * invoke.texi: Added `-fhandle-signatures' in the list of
+ C++ language options. Added explanation for this option.
+
+Tue Dec 28 21:10:03 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-init.c (expand_vec_init): Remove comptypes test, as it is too
+ harsh here.
+
+Tue Dec 28 13:42:22 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-pt.c (do_pending_expansions): Decide to expand a template
+ member function, based upon it's class type, not the class type of
+ the first place it was declared.
+
+Tue Dec 28 05:42:31 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-class.c (is_normal): New routine, use to determine when the
+ given binfo is the normal one. (The one that should have the simple
+ vtable name.)
+ * cp-class.c (modify_other_vtable_entries): Use DECL_ASSEMBLER_NAME
+ to check if two fndecls are `the same'. Sometimes this routine can
+ modify the main vtable, and normal should be 1, in that case, so use
+ is_normal() to determine if this is the main vtable for the class.
+ Don't recurse down virtual bases, as they are shared, and we take
+ care of them elsewhere.
+ * cp-class.c (modify_vtable_entries): If we have already updated the
+ vtable with the new virtual, don't do it again.
+ * cp-class.c (finish_struct): Set CLASSTYPE_VFIELD_PARENT as
+ appropriate. Do virtual function overriding in virtual bases, after
+ normal overriding, so that the base function list in DECL_VINDEX is
+ not overridden, before we have a chance to run through the list.
+ Use DECL_ASSEMBLER_NAME to check if two fndecls are `the same'.
+ Make sure we pass the right address into modify_vtable_entries.
+ * cp-tree.h (CLASSTYPE_VFIELD_PARENT): New field to indicate which
+ binfo is the one that has the vtable that we based our vtable on.
+
+Fri Dec 24 09:40:52 1993 Michael Tiemann <tiemann@blues.cygnus.com>
+
+ * cp-typeck.c (c_expand_start_case): Use default_conversion to
+ convert expression from reference type if necessary.
+
+Wed Dec 22 17:58:43 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-typeck.c (build_unary_op): Make sure that it's a TREE_LIST before
+ trying to read its TREE_VALUE.
+
+ * cp-class.c (finish_struct_methods): Clear DECL_IN_AGGR_P here.
+ (finish_struct): Instead of here.
+
+Tue Dec 21 14:34:25 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.c (list_hash_lookup_or_cons): Make sure the type doesn't
+ have TYPE_PTRMEMFUNC_P set before we try to build its
+ CLASSTYPE_ID_AS_LIST.
+ (get_decl_list): Likewise, when trying to read it.
+
+ * cp-tree.h (VTABLE_NAME): No def with NO_{DOLLAR,DOT} defined.
+ (VTABLE_NAME_P): Use it instead of VTABLE_NAME_FORMAT.
+
+Mon Dec 20 13:35:03 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-typeck.c (rationalize_conditional_expr): New function.
+ (unary_complex_lvalue): Use it.
+ (build_modify_expr): Use it, since trying to do an ADDR_EXPR of it
+ with build_unary_op won't cut it. Don't wrap the COND_EXPR with a
+ SAVE_EXPR either.
+
+ * cp-decl2.c (explicit_warn_return_type): Deleted variable.
+ (lang_decode_option): Set warn_return_type, not explicit_*, for
+ -Wreturn-type and -Wall. This is what rest_of_compilation uses to
+ decide if it should go into jump_optimize or not.
+ * cp-tree.h (explicit_warn_return_type): Deleted.
+ * cp-decl.c (grokdeclarator): Use warn_return_type, not explicit_*.
+ (finish_function): Also complain about no return in a non-void fn if
+ we're being pedantic (don't rely on use of -Wreturn-type).
+
+Fri Dec 17 15:45:46 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-decl.c (grokdeclarator): Forbid declaration of a function as
+ static if it's being done inside another function.
+
+ * cp-search.c (compute_visibility): Check for friendship both ways.
+
+Fri Dec 17 14:28:25 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-cvt.c (build_default_binary_type_conversion): Make error
+ messages more helpful.
+
+ * cp-error.c (op_as_string): New function, returns "operator =="
+ given EQ_EXPR or suchlike.
+
+Fri Dec 17 13:28:11 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-call.c (print_n_candidates): New function.
+ (build_overload_call_real): Use it when we complain about a call
+ being ambiguous.
+
+Fri Dec 17 12:41:17 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-call.c (build_method_call): Fix checking for static call
+ context.
+
+ * cp-method.c (build_opfncall): Call build_indirect_ref on argument
+ to operator new.
+
+ * cp-init.c (build_new): Don't mess with rval when building
+ indirect ref.
+
+Thu Dec 16 16:48:05 1993 Kung Hsu <kung@cirdan.cygnus.com>
+
+ * cp-lex.c (default_assign_ref_body): add check when TYPE_NESTED_
+ NAME(type) may not be exist. It's not a problem for old compiler.
+
+Thu Dec 16 14:46:06 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (CLASSTYPE_ALTERS_VISIBILITIES_P): Delete macro, it's
+ never used for anything.
+ (struct lang_type, member type_flags): Delete field
+ `alters_visibility', and up `dummy' by 1.
+ * cp-class.c (finish_base_struct): Delete code that copies the
+ setting of CLASSTYPE_ALTERS_VISIBILITIES_P.
+ (finish_struct): Delete code that sets it.
+
+Thu Dec 16 14:44:39 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c, cp-init.c, cp-typeck.c: Fix arguments to
+ build_method_call that I messed up before.
+
+ * cp-search.c (get_base_distance): If protect > 1, allow immediate
+ private base.
+
+ * cp-class.c (finish_base_struct): Set cant_synth_* correctly.
+ (finish_struct): Likewise. Well, nigh-correctly; it won't deal
+ properly with the case where a class contains an object of an
+ ambiguous base class which has a protected op=. Should be fixed
+ when the access control code gets overhauled.
+ (finish_struct_methods): Set TYPE_HAS_NONPUBLIC_* correctly.
+
+Thu Dec 16 12:17:06 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-lex.c (real_yylex): Turn the code back on that deals with
+ __FUNCTION__ and __PRETTY_FUNCTION__. Don't use lookup_name, to
+ avoid the ambiguity problems that led to it being turned off in the
+ first place.
+
+ * cp-method.c (hack_identifier): Also check for a TYPE_PTRMEMFUNC_P
+ to see if something is a method.
+
+Wed Dec 15 18:35:58 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-typeck.c (build_modify_expr): Avoid error messages on small
+ enum bit fields.
+ * cp-typeck.c (convert_for_assignment): Add missing argument to
+ cp_warning and cp_pedwarn calls.
+
+Wed Dec 15 18:25:32 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-parse.y (member_init): ANSI C++ doesn't forbid old-style base
+ initializers; it's just anachronistic.
+
+ * cp-decl.c (finish_decl): Don't require external-linkage arrays
+ to have a complete type at declaration time when pedantic.
+
+Tue Dec 14 11:37:23 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c (pushdecl): Don't set DECL_CONTEXT if it's already set.
+
+ * cp-call.c (build_method_call): Don't dereference pointer given
+ as instance.
+
+ * cp-decl.c (finish_function): Don't pass pointer to
+ build_method_call.
+ (finish_function): Likewise.
+
+ * cp-typeck.c (build_x_function_call): Likewise.
+
+ * cp-method.c (build_component_type_expr): Likewise.
+
+ * cp-init.c (build_member_call): Likewise.
+ (build_new): Likewise.
+
+Mon Dec 13 18:04:33 1993 Kung Hsu <kung@cirdan.cygnus.com>
+
+ * cp-decl.c (xref_tag): fix regression created by changes made
+ in Dec. 7 1993.
+ * cp-decl.c (xref_defn_tag): fix parallel nested class problem.
+
+Fri Dec 10 12:40:25 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-call.c (compute_conversion_costs_ansi) [DEBUG_MATCHING]: Print
+ out the final evaluation of the function, so we can see if ELLIPSIS,
+ USER, and EVIL were set at the end.
+
+ * cp-call.c (convert_harshness_ansi): When the parm isn't an lvalue,
+ only go for setting TRIVIAL_CODE if we are dealing with types that
+ are compatible.
+
+Thu Dec 9 18:27:22 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-decl.c (flag_huge_objects): New flag to allow large objects.
+ * toplev.c (lang_options): Likewise.
+ * cp-decl2.c (flag_huge_objects, lang_f_options): Likewise.
+ * cp-decl.c (delta_type_node): New type for delta entries.
+ * cp-tree.h (delta_type_node): Likewise.
+ * cp-decl.c (init_decl_processing): Setup delta_type_node.
+ * cp-decl.c (init_decl_processing, build_ptrmemfunc_type): Use
+ delta_type_node instead of short_integer_type_node.
+ * cp-class.c (build_vtable_entry): Likewise.
+
+Thu Dec 9 16:19:05 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (OPERATOR_TYPENAME_P): Define outside of
+ NO_{DOLLAR,DOT} macro checks, so it always gets defined.
+ (VTABLE_NAME_P): Define for NO_DOT && NO_DOLLAR_IN_LABEL.
+
+Wed Dec 8 17:38:06 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-decl.c (finish_decl): Make sure things that can go into
+ "common", do go into common, if -fcommon is given.
+
+Wed Dec 8 13:01:54 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-call.c (print_harshness) [DEBUG_MATCHING]: New function.
+ (compute_conversion_costs_ansi) [DEBUG_MATCHING]: Print out
+ argument matching diagnostics to make instantly clear what the
+ compiler is doing.
+
+ * cp-call.c (convert_harshness_ansi): If the parm isn't an lvalue,
+ then check to see if the penalty was increased due to
+ signed/unsigned mismatch, and use a TRIVIAL_CODE if it wasn't.
+
+Tue Dec 7 18:29:14 1993 Kung Hsu <kung@cirdan.cygnus.com>
+
+ * cp-decl.c (xref_tag, pushtag): Fix nested class search/resolution
+ problem.
+
+Tue Dec 7 16:09:34 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-class.c (finish_struct): Before synthesizing methods, if no
+ methods have yet been declared then set nonprivate_method. Don't
+ set non_private method after synthesizing a method.
+
+ * cp-lex.c (extract_interface_info): If flag_alt_external_templates
+ is set, tie emitted code to the location of template instantiation,
+ rather than definition.
+
+ * cp-tree.h: Declare flag_alt_external_templates.
+
+ * cp-decl2.c (lang_decode_option): Support -falt-external-templates.
+
+ * toplev.c (lang_options): Likewise.
+
+Mon Oct 4 12:50:02 1993 Chip Salzenberg <chip@fin.uucp>
+
+ [changes propagated from 930810 snapshot]
+ * cp-decl.c (init_decl_processing): Make long long available for use
+ as SIZE_TYPE and PTRDIFF_TYPE.
+ (finish_decl): Allow file-scope static incomplete array.
+ (grokdeclarator): Don't pass on const and volatile fron function
+ value type to function type.
+ Warn here for volatile fn returning non-void type.
+ * cp-parse.y (attrib): Accept attributes `volatile' with alias
+ `noreturn', and `const'.
+ * cp-typeck.c (default_conversion): Don't lose const and volatile.
+ (build_binary_op_nodefault): Generate pedantic warning for comparison
+ of complete pointer type with incomplete pointer type.
+ (build_c_cast): Be careful that null pointer constant be INTEGER_CST.
+
+Tue Dec 7 10:46:48 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-init.c (expand_vec_init): When creating a temporary for copying
+ arrays, use the type of the source, not the target.
+
+ * cp-cvt.c (convert): Pass an argument for errtype to
+ convert_to_reference.
+
+ * cp-error.c (dump_expr, COMPONENT_REF & CALL_EXPR): Deal with
+ methods, -> and `this'.
+
+Mon Dec 6 17:12:33 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-error.c (parm_as_string): New function; returns `this' or arg
+ number. Corresponds to %P.
+ (dump_expr): Deal with method calls.
+
+ * cp-cvt.c (convert_to_reference): Stop using warn_for_assignment.
+ * cp-typeck.c (convert_for_assignment): Likewise.
+ (warn_for_assignment): Lose.
+
+Mon Dec 6 11:33:35 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-call.c (ideal_candidate_ansi): Delete code that was never
+ doing anything useful. Instead, sort once, and DO NOT wipe
+ out any codes with EVIL_CODE, since that's what we use as a
+ marker for the end of the list of candidates.
+
+ * cp-cvt.c (convert_to_aggr): Make sure to always set H_LEN.
+
+Mon Dec 6 12:49:17 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-init.c (get_aggr_from_typedef): New function, like
+ is_aggr_typedef but returns the _TYPE.
+
+ * cp-call.c, cp-init.c, cp-method.c: Eradicate err_name.
+
+Sun Dec 5 18:12:48 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-lex.c (readescape): Pedwarn when a hex escape is out of range.
+
+Thu Nov 25 23:50:19 1993 Chip Salzenberg <chip@fin.uucp>
+
+ Delay language context change until beginning of next decl.
+
+ * cp-lex.h (c_header_level): Removed.
+ (pending_lang_change): Declared.
+ * cp-lex.c (c_header_level): Renamed from in_c_header, made static.
+ (pending_lang_change): Defined.
+ (check_newline): Rework code that recognizes line number and
+ filename changes. Instead of pushing and popping lang context,
+ increment and decrement pending_lang_change.
+ (do_pending_lang_change): Push and pop lang context according
+ to value of pending_lang_change.
+ * cp-parse.y (extdefs): Use lang_extdef instead of extdef.
+ (extdef): Same as extdef, but call do_pending_lang_change() first.
+
+Mon Nov 15 15:39:15 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-typeck.c (build_binary_op_nodefault): Warn for ordered
+ compare of ptr with 0 only if pedantic in both cases.
+
+Thu Nov 25 13:31:37 1993 Chip Salzenberg <chip@fin.uucp>
+
+ Reinstate the below patch, which got lost in the Cygnus merge:
+ Tue Nov 23 13:59:24 1993 Hallvard B Furuseth (hbf@durin.uio.no)
+ * cp-parse.y (maybe_type_qual): Don't fail to set $$.
+
+Wed Nov 17 19:03:30 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-parse.y (attrib): Allow "ident(ident)" like the C front end.
+
+Fri Oct 22 20:43:37 1993 Paul Eggert <eggert@twinsun.com>
+
+ * cp-lex.c (real_yylex): Diagnose floating point constants
+ that are too large.
+
+Wed Nov 17 19:10:37 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-type2.c (build_functional_cast): ARM page 16: When a class
+ and an object, function or enumerator are declared in the same
+ scope with the same name, the class name is hidden.
+
+Wed Nov 17 19:07:18 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-call.c (convert_harshness_ansi): Distinguish float, double,
+ and long double from each other when overloading.
+ (compute_conversion_costs_{ansi,old}, build_method_call,
+ build_overlay_call_real, convert_to_aggr): Always set and
+ always use H_LEN member of candidate structure.
+
+Mon Oct 11 23:10:53 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-decl.c (duplicate_decls): Note redeclarations of library
+ functions, and generate distinct warnings for them.
+
+Mon Oct 4 12:26:49 1993 Chip Salzenberg <chip@fin.uucp>
+
+ Support format warnings in G++.
+
+ * cp-tree.h: Protect against multiple inclusion.
+ Declare all public functions in c-common.c (copy from c-tree.h).
+ (STDIO_PROTO): Define.
+ (warn_format): Declare.
+ (record_format_info): Remove declaration.
+ * cp-decl.c (init_decl_processing): Call init_function_format_info.
+ * cp-decl2.c (lang_decode_option): Make "-Wall" include warn_format.
+ * cp-typeck.c (build_function_call_real): Call check_function_format.
+ (record_format_info): Remove -- obsolete stub.
+
+Sat Jul 24 12:04:29 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-decl.c (duplicate_decls): Don't warn for non-extern var decl
+ following an extern one (for -Wredundant-decls).
+ * cp-parse.y (primary): In statement expression case, if compstmt
+ returns something other than a BLOCK, return it unchanged.
+
+Thu Dec 2 20:44:58 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-decl.c (warn_extern_redeclared_static): New function made
+ from code extracted from pushdecl.
+ (duplicate_decls, pushdecl): Call new function.
+ (lookup_name_current_level): Allow for IDENTIFIER_GLOBAL_VALUE
+ to be a TREE_LIST when function is declared in 'extern "C" {}'.
+
+Fri Dec 3 16:01:10 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-class.c (duplicate_tag_error): Use cp_error.
+ (finish_base_struct): Check for ambiguity with direct base, and don't
+ generate op= or copy ctor if it exists.
+
+Fri Dec 3 15:32:34 1993 Kung Hsu <kung@cirdan.cygnus.com>
+
+ * cp-init.c (expand_member_init): when initializer name is null,
+ don't try to build it now because emit_base_init will handle it.
+
+Fri Dec 3 12:28:59 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-lex.c (init_lex): Initialize input_filename to "<internal>" for
+ code such as ExceptionHandler::operator=.
+
+Fri Dec 3 10:32:08 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c (grokdeclarator): Don't try to print out dname when
+ complaining about arrays of references if decl_context==TYPENAME,
+ since it will be null.
+
+ * cp-decl2.c: Default to flag_ansi_overloading.
+
+Thu Dec 2 18:05:56 1993 Kung Hsu <kung@cirdan.cygnus.com>
+
+ * cp-call.c (build_method_call): use binfo from instance if it's
+ different from binfo (basetype_path) passed from above.
+
+Wed Nov 17 19:14:29 1993 Chip Salzenberg <chip@fin.uucp>
+
+ cp-error.c (dump_expr): Use unsigned chars to output a
+ TREE_REAL_CST in hex.
+
+Thu Dec 2 11:05:48 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-class.c (finish_struct): Fix typo in setting
+ cant_synth_asn_ref.
+
+ * cp-tree.h (TYPE_NESTED_NAME): New macro, does
+ DECL_NESTED_TYPENAME (TYPE_NAME (NODE)).
+
+ * cp-lex.c (default_copy_constructor_body): Change
+ DECL_NAME (TYPE_NAME (btype)) to TYPE_NESTED_NAME (btype).
+ (default_assign_ref_body): Likewise.
+ (default_copy_constructor_body): Call operator= explicitly for
+ base classes that have no constructor.
+
+Thu Dec 2 10:47:15 1993 Michael Tiemann <tiemann@blues.cygnus.com>
+
+ * cp-call.c (build_method_call): If the instance variable is
+ converted to error_mark_node when we're trying to convert it to the
+ base type of a method we're looking up, return error_mark_node.
+
+Thu Dec 2 10:41:16 1993 Torbjorn Granlund <tege@cygnus.com>
+
+ * cp-typeck.c (build_binary_op_nodefault): In *_DIV_EXPR *_MOD_EXPR
+ cases, tests for unsigned operands by peeking inside a NOP_EXPR.
+
+Wed Dec 1 13:33:34 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-call.c (compute_conversion_costs_ansi): Use the size of struct
+ harshness_code, not the size of short, for clearing out the
+ ansi_harshness.
+
+ * cp-call.c (print_candidates): New function.
+ (build_method_call): When we had some candidates, but didn't get a
+ usable match, don't report that we got an error with the first
+ candidate. Instead, say there were no matches, and list the
+ candidates with print_candidates. In the second pass, make sure we
+ clear out ever_seen, so we can accurately count the number of
+ functions that qualified.
+
+Wed Dec 1 09:53:59 1993 Torbjorn Granlund <tege@cygnus.com>
+
+ * cp-typeck.c (build_binary_op_nodefault): Shorten for *_MOD_EXPR
+ only if op1 is known to be != -1.
+ (build_binary_op_nodefault): Handle *_DIV_EXPR likewise.
+
+Tue Nov 30 14:07:26 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-method.c (hack_identifier): If the field itself is private, and
+ not from a private base class, say so.
+
+Mon Nov 29 03:00:56 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c (grokdeclarator): Always warn on initialization of
+ const member.
+
+Wed Nov 24 00:49:35 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-class.c (finish_struct): Set TYPE_GETS_CONST_* properly.
+ (finish_base_struct): Set cant_synth_asn_ref properly.
+
+ * cp-lex.c (cons_up_default_function): Add section for operator=.
+ (default_assign_ref_body): New function, mostly cribbed from
+ default_copy_constructor_body.
+
+ * cp-class.c (base_info): Add members cant_synth_copy_ctor,
+ cant_synth_asn_ref, no_const_asn_ref.
+ (finish_base_struct): Update no_const_asn_ref, note that you should
+ update cant_synth_*, propagate TYPE_GETS_ASSIGN_REF.
+ (finish_struct): Add decls for cant_synth_*, no_const_asn_ref, and
+ initialize them properly. Set no_const_asn_ref properly. Set
+ cant_synth_* in some of the situations where they should be set.
+ Propagate TYPE_GETS_ASSIGN_REF. Use cant_synth_copy_ctor. Add call
+ to cons_up_default_function for operator=.
+
+Tue Nov 23 20:24:58 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-cvt.c (convert_force): Add code to perform casting of pointer
+ to member function types.
+ * cp-typeck.c (build_ptrmemfunc): Add FORCE parameter to indicate
+ when the conversion should be done, regardless.
+ * cp-tree.h (build_ptrmemfunc): Likewise.
+ * cp-type2.c (digest_init): Likewise.
+ * cp-typeck.c (convert_for_assignment): Likewise.
+
+Tue Nov 23 18:06:58 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-error.c (dump_expr): Do the right thing for variables of
+ reference type.
+
+ * cp-decl.c (grok_op_properties): Set TYPE_HAS_ASSIGN_REF
+ and its kin properly.
+ (xref_tag): Propagate TYPE_GETS_ASSIGN_REF.
+
+Tue Nov 23 12:26:13 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-method.c (build_opfncall): Don't count pointer to member
+ functions as aggregates here, as we don't want to look up methods in
+ them. The compiler would core dump if we did, as they don't have
+ normal names.
+ * cp-typeck.c (build_indirect_ref): Improve wording on error
+ message.
+
+Mon Nov 22 14:22:23 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c (grok_op_properties): Allow operator?: with pedwarn
+ (since it's supported in other compiler bits).
+
+ * cp-method.c (report_type_mismatch): Use cp_error; ignore err_name
+ argument.
+
+ * cp-error.c (dump_function_decl): Don't print return type for
+ constructors and destructors.
+
+ * cp-cvt.c (cp_convert_to_pointer): Import code from
+ convert_to_pointer so we can return error_mark_node in the case of an
+ error, and to allow more meaningful error messages.
+ (build_type_conversion): Don't go through void* when trying
+ to convert to a pointer type.
+
+ * cp-decl.c (grokfndecl): Move call to grok_op_properties back
+ after grokclassfn so that it's dealing with the right decl.
+ (grok_op_properties): Don't assert !methodp for op new and op delete.
+
+ * cp-init.c (build_delete): Don't use TYPE_BUILT_IN (there are now
+ no uses of it in the compiler).
+
+ * cp-call.c (build_scoped_method_call): Fix for destructors of simple
+ types.
+ (build_method_call): Likewise.
+
+Fri Nov 19 12:59:38 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.c (count_functions): Abstraction function.
+
+ * cp-call.c (build_overload_call_real): Deal with new overloading
+ properly, remove dead code.
+
+ * gcc.c (default_compilers): Generate and use .ii files in the
+ intermediate stage of compiling C++ source.
+
+Fri Nov 19 11:26:09 1993 Jim Wilson <wilson@sphagnum.cygnus.com>
+
+ * cp-expr.c (cplus_expand_expr): Make call_target a valid memory
+ address before using it, so it can be later safely compared.
+
+Fri Nov 12 15:30:27 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-pt.c (tsubst): Deal with new overloading.
+
+ * cp-typeck.c (fntype_p): is the arg function type?
+ (comp_target_parms): pedwarn on conversion from (anything) to (...).
+ (build_x_function_call): Deal with new overloading.
+
+ * cp-tree.c (decl_list_length): Deal with new overloading.
+ (decl_value_member): Like value_member, but for DECL_CHAINs.
+
+ * cp-decl.c (duplicate_decls): Deal with new overloading.
+ (start_decl): Likewise.
+
+ * cp-class.c (instantiate_type): Deal with new overloading.
+
+ * cp-call.c (convert_harshness_ansi): Deal with new overloading.
+ (convert_harshness_old): Deal with new overloading.
+ (build_overload_call_real): Likewise.
+
+Mon Nov 8 13:50:49 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.c (get_unique_fn): New function; returns FUNCTION_DECL
+ if unambiguous, NULL_TREE otherwise.
+ (get_first_fn): Returns the first appropriate FUNCTION_DECL.
+ (is_overloaded_fn): Returns whether or not the passed tree is
+ a function or list of functions.
+
+ * cp-init.c (init_init_processing): use `get_first_fn' to find
+ the FUNCTION_DEFN for new and delete.
+
+ * cp-decl.c (push_overloaded_decl): Use new overloading strategy, cut
+ code size in half (I spit on special cases).
+
+Tue Sep 7 20:03:33 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c: Allow references and template type parameters as well
diff --git a/gnu/usr.bin/gcc/cp/NEWS b/gnu/usr.bin/gcc/cp/NEWS
new file mode 100644
index 00000000000..ff2d5124f52
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/NEWS
@@ -0,0 +1,180 @@
+*** Changes since G++ version 2.7.2:
+
+* A public review copy of the December 1996 Draft of the ANSI/ISO C++
+ proto-standard is now available. See
+
+ http://www.cygnus.com/misc/wp/
+
+ for more information.
+
+* g++ now uses a new implementation of templates. The basic idea is that
+ now templates are minimally parsed when seen and then expanded later.
+ This allows conformant early name binding and instantiation controls,
+ since instantiations no longer have to go through the parser.
+
+ What you get:
+
+ + Inlining of template functions works without any extra effort or
+ modifications.
+ + Instantiations of class templates and methods defined in the class
+ body are deferred until they are actually needed (unless
+ -fexternal-templates is specified).
+ + Nested types in class templates work.
+ + Static data member templates work.
+ + Member function templates are now supported.
+ + Partial specialization of class templates is now supported.
+ + Explicit specification of template parameters to function templates
+ is now supported.
+
+ Things you may need to fix in your code:
+
+ + Syntax errors in templates that are never instantiated will now be
+ diagnosed.
+ + Types and class templates used in templates must be declared
+ first, or the compiler will assume they are not types, and fail.
+ + Similarly, nested types of template type parameters must be tagged
+ with the 'typename' keyword, except in base lists. In many cases,
+ but not all, the compiler will tell you where you need to add
+ 'typename'. For more information, see
+
+ http://www.cygnus.com/misc/wp/dec96pub/template.html#temp.res
+
+ + Guiding declarations are no longer supported. Function declarations,
+ including friend declarations, do not refer to template instantiations.
+ You can restore the old behavior with -fguiding-decls until you fix
+ your code.
+
+ Other features:
+
+ + Default function arguments in templates will not be evaluated (or
+ checked for semantic validity) unless they are needed. Default
+ arguments in class bodies will not be parsed until the class
+ definition is complete.
+ + The -ftemplate-depth-NN flag can be used to increase the maximum
+ recursive template instantiation depth, which defaults to 17. If you
+ need to use this flag, the compiler will tell you.
+ + Explicit instantiation of template constructors and destructors is
+ now supported. For instance:
+
+ template A<int>::A(const A&);
+
+ Still not supported:
+
+ + Member class templates.
+ + Template template parameters.
+ + Template friends.
+
+* Exception handling support has been significantly improved and is on by
+ default. This can result in significant runtime overhead. You can turn
+ it off with -fno-exceptions.
+
+* RTTI support has been rewritten to work properly and is now on by default.
+ This means code that uses virtual functions will have a modest space
+ overhead. You can use the -fno-rtti flag to disable RTTI support.
+
+* On ELF systems, duplicate copies of symbols with 'initialized common'
+ linkage (such as template instantiations, vtables, and extern inlines)
+ will now be discarded by the GNU linker, so you don't need to use -frepo.
+ This support requires GNU ld from binutils 2.8 or later.
+
+* The overload resolution code has been rewritten to conform to the latest
+ C++ Working Paper. Built-in operators are now considered as candidates
+ in operator overload resolution. Function template overloading chooses
+ the more specialized template, and handles base classes in type deduction
+ and guiding declarations properly. In this release the old code can
+ still be selected with -fno-ansi-overloading, although this is not
+ supported and will be removed in a future release.
+
+* Standard usage syntax for the std namespace is supported; std is treated
+ as an alias for global scope. General namespaces are still not supported.
+
+* New flags:
+
+ + New flags -Wsign-promo (warn about potentially confusing promotions
+ in overload resolution), -Wno-pmf-conversion (don't warn about
+ converting from a bound member function pointer to function pointer).
+
+ + A flag -Weffc++ has been added for violations of some of the style
+ guidelines in Scott Meyers' _Effective C++_ books.
+
+ + -Woverloaded-virtual now warns if a virtual function in a base
+ class is hidden in a derived class, rather than warning about
+ virtual functions being overloaded (even if all of the inherited
+ signatures are overridden) as it did before.
+
+ + -Wall no longer implies -W. The new warning flag, -Wsign-compare,
+ included in -Wall, warns about dangerous comparisons of signed and
+ unsigned values. Only the flag is new; it was previously part of
+ -W.
+
+ + The new flag, -fno-weak, disables the use of weak symbols.
+
+* Synthesized methods are now emitted in any translation units that need
+ an out-of-line copy. They are no longer affected by #pragma interface
+ or #pragma implementation.
+
+* __FUNCTION__ and __PRETTY_FUNCTION__ are now treated as variables by the
+ parser; previously they were treated as string constants. So code like
+ `printf (__FUNCTION__ ": foo")' must be rewritten to
+ `printf ("%s: foo", __FUNCTION__)'. This is necessary for templates.
+
+* local static variables in extern inline functions will be shared between
+ translation units.
+
+* -fvtable-thunks is supported for all targets, and is the default for
+ Linux with glibc 2.x (also called libc 6.x).
+
+* bool is now always the same size as another built-in type. Previously,
+ a 64-bit RISC target using a 32-bit ABI would have 32-bit pointers and a
+ 64-bit bool. This should only affect Irix 6, which was not supported in
+ 2.7.2.
+
+* new (nothrow) is now supported.
+
+* Synthesized destructors are no longer made virtual just because the class
+ already has virtual functions, only if they override a virtual destructor
+ in a base class. The compiler will warn if this affects your code.
+
+* The g++ driver now only links against libstdc++, not libg++; it is
+ functionally identical to the c++ driver.
+
+* (void *)0 is no longer considered a null pointer constant; NULL in
+ <stddef.h> is now defined as __null, a magic constant of type (void *)
+ normally, or (size_t) with -ansi.
+
+* The name of a class is now implicitly declared in its own scope; A::A
+ refers to A.
+
+* Local classes are now supported.
+
+* __attribute__ can now be attached to types as well as declarations.
+
+* The compiler no longer emits a warning if an ellipsis is used as a
+ function's argument list.
+
+* Definition of nested types outside of their containing class is now
+ supported. For instance:
+
+ struct A {
+ struct B;
+ B* bp;
+ };
+
+ struct A::B {
+ int member;
+ };
+
+* On the HPPA, some classes that do not define a copy constructor
+ will be passed and returned in memory again so that functions
+ returning those types can be inlined.
+
+*** The g++ team thanks everyone that contributed to this release,
+ but especially:
+
+* Joe Buck <jbuck@synopsys.com>, the maintainer of the g++ FAQ.
+* Brendan Kehoe <brendan@cygnus.com>, who coordinates testing of g++.
+* Jason Merrill <jason@cygnus.com>, the g++ maintainer.
+* Mark Mitchell <mmitchell@usa.net>, who implemented member function
+ templates and explicit qualification of function templates.
+* Mike Stump <mrs@wrs.com>, the previous g++ maintainer, who did most of
+ the exception handling work.
diff --git a/gnu/usr.bin/gcc/cp/cp-tree.def b/gnu/usr.bin/gcc/cp/cp-tree.def
new file mode 100644
index 00000000000..65d20a71e5e
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/cp-tree.def
@@ -0,0 +1,169 @@
+/* This file contains the definitions and documentation for the
+ additional tree codes used in the GNU C++ compiler (see tree.def
+ for the standard codes).
+ Copyright (C) 1987, 1988, 1990, 1993 Free Software Foundation, Inc.
+ Hacked by Michael Tiemann (tiemann@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. */
+
+
+/* Reference to the contents of an offset
+ (a value whose type is an OFFSET_TYPE).
+ Operand 0 is the object within which the offset is taken.
+ Operand 1 is the offset. The language independent OFFSET_REF
+ just won't work for us. */
+DEFTREECODE (OFFSET_REF, "offset_ref", "r", 2)
+
+/* For DELETE_EXPR, operand 0 is the store to be destroyed.
+ Operand 1 is the value to pass to the destroying function
+ saying whether the store should be deallocated as well. */
+DEFTREECODE (DELETE_EXPR, "dl_expr", "e", 2)
+DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", "e", 2)
+
+/* Value is reference to particular overloaded class method.
+ Operand 0 is the class name (an IDENTIFIER_NODE);
+ operand 1 is the field (also an IDENTIFIER_NODE).
+ The COMPLEXITY field holds the class level (usually 0). */
+DEFTREECODE (SCOPE_REF, "scope_ref", "r", 2)
+
+/* When composing an object with a member, this is the result.
+ Operand 0 is the object. Operand 1 is the member (usually
+ a dereferenced pointer to member). */
+DEFTREECODE (MEMBER_REF, "member_ref", "r", 2)
+
+/* Type conversion operator in C++. TREE_TYPE is type that this
+ operator converts to. Operand is expression to be converted. */
+DEFTREECODE (TYPE_EXPR, "type_expr", "e", 1)
+
+/* For NEW_EXPR, operand 0 is function which performs initialization,
+ operand 1 is argument list to initialization function,
+ and operand 2 is the slot which was allocated for this expression. */
+DEFTREECODE (NEW_EXPR, "nw_expr", "e", 3)
+DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", "e", 3)
+
+/* A throw expression. operand 0 is the expression, if there was one,
+ else it is NULL_TREE. */
+DEFTREECODE (THROW_EXPR, "throw_expr", "e", 1)
+
+/* Initialization of a vector, used in build_new. Operand 0 is the target
+ of the initialization, operand 1 is the initializer, and operand 2 is
+ the number of elements. */
+DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", "e", 3)
+
+/* Template definition. The following fields have the specified uses,
+ although there are other macros in cp-tree.h that should be used for
+ accessing this data.
+ DECL_ARGUMENTS template parm vector
+ DECL_TEMPLATE_INFO template text &c
+ DECL_VINDEX list of instantiations already produced;
+ only done for functions so far
+ For class template:
+ DECL_INITIAL associated templates (methods &c)
+ DECL_RESULT null
+ For non-class templates:
+ TREE_TYPE type of object to be constructed
+ DECL_RESULT decl for object to be created
+ (e.g., FUNCTION_DECL with tmpl parms used)
+ */
+DEFTREECODE (TEMPLATE_DECL, "template_decl", "d", 0)
+
+/* Index into a template parameter list. This parameter must be a type.
+ Use TYPE_FIELDS to find parmlist and index. */
+DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", "t", 0)
+
+/* A type designated by 'typename T::t'. */
+DEFTREECODE (TYPENAME_TYPE, "typename_type", "t", 0)
+
+/* Index into a template parameter list. This parameter must not be a
+ type. */
+DEFTREECODE (TEMPLATE_CONST_PARM, "template_const_parm", "c", 3)
+
+/* A thunk is a stub function.
+
+ Thunks are used to implement multiple inheritance:
+ At run-time, such a thunk subtracts THUNK_DELTA (an int, not a tree)
+ from the this pointer, and then jumps to DECL_INITIAL
+ (which is an ADDR_EXPR whose operand is a FUNCTION_DECL).
+
+ Other kinds of thunks may be defined later. */
+DEFTREECODE (THUNK_DECL, "thunk_decl", "d", 0)
+
+/* A namespace declaration. */
+DEFTREECODE (NAMESPACE_DECL, "namespace_decl", "d", 0)
+
+/* A using declaration. DECL_INITIAL contains the specified scope.
+ This is not an alias, but is later expanded into multiple aliases. */
+DEFTREECODE (USING_DECL, "using_decl", "d", 0)
+
+/* An un-parsed default argument. Looks like an IDENTIFIER_NODE. */
+DEFTREECODE (DEFAULT_ARG, "default_arg", "c", 2)
+
+/* A template-id, like foo<int>. The first operand is the template.
+ The second is the list of explicitly specified arguments. The
+ template will be a FUNCTION_DECL, TEMPLATE_DECL, or a list of
+ overloaded functions and templates if the template-id refers to
+ a global template. If the template-id refers to a member template,
+ the template will will be an IDENTIFIER_NODE. */
+DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", "e", 2)
+
+/* A whole bunch of tree codes for the initial, superficial parsing of
+ templates. */
+DEFTREECODE (LOOKUP_EXPR, "lookup_expr", "e", 2)
+DEFTREECODE (MODOP_EXPR, "modop_expr", "e", 3)
+DEFTREECODE (CAST_EXPR, "cast_expr", "1", 1)
+DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", "1", 1)
+DEFTREECODE (CONST_CAST_EXPR, "const_cast_expr", "1", 1)
+DEFTREECODE (STATIC_CAST_EXPR, "static_cast_expr", "1", 1)
+DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", "1", 1)
+DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", "1", 1)
+DEFTREECODE (ARROW_EXPR, "arrow_expr", "e", 1)
+DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", "e", 2)
+DEFTREECODE (TYPEID_EXPR, "typeid_expr", "e", 1)
+
+DEFTREECODE (EXPR_STMT, "expr_stmt", "e", 1)
+DEFTREECODE (COMPOUND_STMT, "compound_stmt", "e", 1)
+DEFTREECODE (DECL_STMT, "decl_stmt", "e", 3)
+DEFTREECODE (IF_STMT, "if_stmt", "e", 3)
+DEFTREECODE (FOR_STMT, "for_stmt", "e", 4)
+DEFTREECODE (WHILE_STMT, "while_stmt", "e", 2)
+DEFTREECODE (DO_STMT, "do_stmt", "e", 2)
+DEFTREECODE (RETURN_STMT, "return_stmt", "e", 1)
+DEFTREECODE (BREAK_STMT, "break_stmt", "e", 0)
+DEFTREECODE (CONTINUE_STMT, "continue_stmt", "e", 0)
+DEFTREECODE (SWITCH_STMT, "switch_stmt", "e", 2)
+DEFTREECODE (GOTO_STMT, "goto_stmt", "e", 1)
+
+DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", "e", 2)
+DEFTREECODE (CASE_LABEL, "case_label", "e", 2)
+DEFTREECODE (RETURN_INIT, "return_init", "e", 2)
+DEFTREECODE (TRY_BLOCK, "try_stmt", "e", 2)
+DEFTREECODE (HANDLER, "catch_stmt", "e", 2)
+
+DEFTREECODE (IDENTITY_CONV, "identity_conv", "e", 1)
+DEFTREECODE (LVALUE_CONV, "lvalue_conv", "e", 1)
+DEFTREECODE (QUAL_CONV, "qual_conv", "e", 1)
+DEFTREECODE (STD_CONV, "std_conv", "e", 1)
+DEFTREECODE (PTR_CONV, "ptr_conv", "e", 1)
+DEFTREECODE (PMEM_CONV, "pmem_conv", "e", 1)
+DEFTREECODE (BASE_CONV, "base_conv", "e", 1)
+DEFTREECODE (REF_BIND, "ref_bind", "e", 1)
+DEFTREECODE (USER_CONV, "user_conv", "e", 4)
+DEFTREECODE (AMBIG_CONV, "ambig_conv", "e", 1)
+DEFTREECODE (RVALUE_CONV, "rvalue_conv", "e", 1)
+
+DEFTREECODE (TAG_DEFN, "tag_defn", "e", 0)
diff --git a/gnu/usr.bin/gcc/cp/exception.cc b/gnu/usr.bin/gcc/cp/exception.cc
new file mode 100644
index 00000000000..caaf5892282
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/exception.cc
@@ -0,0 +1,195 @@
+// Functions for Exception Support for -*- C++ -*-
+// Copyright (C) 1994, 1995, 1996 Free Software Foundation
+
+// 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.
+
+// As a special exception, if you link this library with other files,
+// some of which are compiled with GCC, to produce an executable,
+// this library does not by itself 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.
+
+#pragma implementation "exception"
+
+#include "typeinfo"
+#include "exception"
+
+/* Define terminate, unexpected, set_terminate, set_unexpected as
+ well as the default terminate func and default unexpected func. */
+
+extern terminate_handler __terminate_func __attribute__((__noreturn__));
+
+void
+terminate ()
+{
+ __terminate_func ();
+}
+
+void
+__default_unexpected ()
+{
+ terminate ();
+}
+
+static unexpected_handler __unexpected_func = __default_unexpected;
+
+terminate_handler
+set_terminate (terminate_handler func)
+{
+ terminate_handler old = __terminate_func;
+
+ __terminate_func = func;
+ return old;
+}
+
+unexpected_handler
+set_unexpected (unexpected_handler func)
+{
+ unexpected_handler old = __unexpected_func;
+
+ __unexpected_func = func;
+ return old;
+}
+
+void
+unexpected ()
+{
+ __unexpected_func ();
+}
+
+/* C++-specific state about the current exception.
+ This must match init_exception_processing().
+
+ Note that handlers and caught are not redundant; when rethrown, an
+ exception can have multiple active handlers and still be considered
+ uncaught. */
+
+struct cp_eh_info
+{
+ void *value;
+ void *type;
+ void (*cleanup)(void *, int);
+ bool caught;
+ cp_eh_info *next;
+ long handlers;
+};
+
+/* Language-specific EH info pointer, defined in libgcc2. */
+
+extern cp_eh_info *__eh_info; // actually void*
+
+/* Is P the type_info node for a pointer of some kind? */
+
+extern bool __is_pointer (void *);
+
+/* Compiler hook to return a pointer to the info for the current exception.
+ Used by get_eh_info (). */
+
+extern "C" cp_eh_info *
+__cp_exception_info (void)
+{
+ return __eh_info;
+}
+
+/* Compiler hook to push a new exception onto the stack.
+ Used by expand_throw(). */
+
+extern "C" void
+__cp_push_exception (void *value, void *type, void (*cleanup)(void *, int))
+{
+ cp_eh_info *p = new cp_eh_info;
+ p->value = value;
+ p->type = type;
+ p->cleanup = cleanup;
+ p->handlers = 0;
+ p->caught = false;
+ p->next = __eh_info;
+ __eh_info = p;
+}
+
+/* Compiler hook to pop an exception that has been finalized. Used by
+ push_eh_cleanup(). P is the info for the exception caught by the
+ current catch block, and HANDLER determines if we've been called from
+ an exception handler; if so, we avoid destroying the object on rethrow. */
+
+extern "C" void
+__cp_pop_exception (cp_eh_info *p, bool handler)
+{
+ cp_eh_info **q = &__eh_info;
+
+ --p->handlers;
+
+ if (p->handlers > 0 || (handler && p == *q))
+ return;
+
+ for (; *q; q = &((*q)->next))
+ if (*q == p)
+ break;
+
+ if (! *q)
+ terminate ();
+
+ *q = p->next;
+
+ if (p->cleanup)
+ /* 3 is a magic value for destructors; see build_delete(). */
+ p->cleanup (p->value, 3);
+ else if (__is_pointer (p->type))
+ /* do nothing; pointers are passed directly in p->value. */;
+ else
+ delete p->value;
+
+ delete p;
+}
+
+extern "C" void
+__uncatch_exception (void)
+{
+ cp_eh_info *p = __cp_exception_info ();
+ if (p)
+ p->caught = false;
+ /* otherwise __throw will call terminate(); don't crash here. */
+}
+
+extern "C" void
+__throw_bad_cast (void)
+{
+ throw bad_cast ();
+}
+
+extern "C" void
+__throw_bad_typeid (void)
+{
+ throw bad_typeid ();
+}
+
+/* Has the current exception been caught? */
+
+bool
+uncaught_exception ()
+{
+ cp_eh_info *p = __cp_exception_info ();
+ return p && ! p->caught;
+}
+
+const char * exception::
+what () const
+{
+ return typeid (*this).name ();
+}
diff --git a/gnu/usr.bin/gcc/cp/friend.c b/gnu/usr.bin/gcc/cp/friend.c
new file mode 100644
index 00000000000..28c0bb44a68
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/friend.c
@@ -0,0 +1,440 @@
+/* Help friends in C++.
+ Copyright (C) 1997 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.h"
+#include <stdio.h>
+#include "tree.h"
+#include "rtl.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "output.h"
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static void add_friend PROTO((tree, tree));
+static void add_friends PROTO((tree, tree, tree));
+
+/* Friend data structures:
+
+ Lists of friend functions come from TYPE_DECL nodes. Since all
+ aggregate types are automatically typedef'd, these nodes are guaranteed
+ to exist.
+
+ The TREE_PURPOSE of a friend list is the name of the friend,
+ and its TREE_VALUE is another list.
+
+ For each element of that list, either the TREE_VALUE or the TREE_PURPOSE
+ will be filled in, but not both. The TREE_VALUE of that list is an
+ individual function which is a friend. The TREE_PURPOSE of that list
+ indicates a type in which all functions by that name are friends.
+
+ Lists of friend classes come from _TYPE nodes. Love that consistency
+ thang. */
+
+int
+is_friend (type, supplicant)
+ tree type, supplicant;
+{
+ int declp;
+ register tree list;
+
+ if (supplicant == NULL_TREE || type == NULL_TREE)
+ return 0;
+
+ declp = (TREE_CODE_CLASS (TREE_CODE (supplicant)) == 'd');
+
+ if (declp)
+ /* It's a function decl. */
+ {
+ tree list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type));
+ tree name = DECL_NAME (supplicant);
+ tree ctype;
+
+ if (DECL_FUNCTION_MEMBER_P (supplicant))
+ ctype = DECL_CLASS_CONTEXT (supplicant);
+ else
+ ctype = NULL_TREE;
+
+ for (; list ; list = TREE_CHAIN (list))
+ {
+ if (name == TREE_PURPOSE (list))
+ {
+ tree friends = TREE_VALUE (list);
+ for (; friends ; friends = TREE_CHAIN (friends))
+ {
+ if (ctype == TREE_PURPOSE (friends))
+ return 1;
+ if (comptypes (TREE_TYPE (supplicant),
+ TREE_TYPE (TREE_VALUE (friends)), 1))
+ return 1;
+ }
+ break;
+ }
+ }
+ }
+ else
+ /* It's a type. */
+ {
+ if (type == supplicant)
+ return 1;
+
+ list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
+ for (; list ; list = TREE_CHAIN (list))
+ if (supplicant == TREE_VALUE (list))
+ return 1;
+ }
+
+ {
+ tree context;
+
+ if (! declp)
+ {
+ /* Are we a nested or local class? If so, we aren't friends
+ with the CONTEXT. */
+ if (IS_AGGR_TYPE (supplicant))
+ context = NULL_TREE;
+ else
+ context = DECL_CONTEXT (TYPE_MAIN_DECL (supplicant));
+ }
+ else if (DECL_FUNCTION_MEMBER_P (supplicant))
+ context = DECL_CLASS_CONTEXT (supplicant);
+ else
+ context = NULL_TREE;
+
+ if (context)
+ return is_friend (type, context);
+ }
+
+ return 0;
+}
+
+/* Add a new friend to the friends of the aggregate type TYPE.
+ DECL is the FUNCTION_DECL of the friend being added. */
+
+static void
+add_friend (type, decl)
+ tree type, decl;
+{
+ tree typedecl = TYPE_MAIN_DECL (type);
+ tree list = DECL_FRIENDLIST (typedecl);
+ tree name = DECL_NAME (decl);
+
+ while (list)
+ {
+ if (name == TREE_PURPOSE (list))
+ {
+ tree friends = TREE_VALUE (list);
+ for (; friends ; friends = TREE_CHAIN (friends))
+ {
+ if (decl == TREE_VALUE (friends))
+ {
+ cp_warning ("`%D' is already a friend of class `%T'",
+ decl, type);
+ cp_warning_at ("previous friend declaration of `%D'",
+ TREE_VALUE (friends));
+ return;
+ }
+ }
+ TREE_VALUE (list) = tree_cons (error_mark_node, decl,
+ TREE_VALUE (list));
+ return;
+ }
+ list = TREE_CHAIN (list);
+ }
+ DECL_FRIENDLIST (typedecl)
+ = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
+ DECL_FRIENDLIST (typedecl));
+ if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR])
+ {
+ tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
+ if (parmtypes && TREE_CHAIN (parmtypes))
+ {
+ tree parmtype = TREE_VALUE (TREE_CHAIN (parmtypes));
+ if (TREE_CODE (parmtype) == REFERENCE_TYPE
+ && TREE_TYPE (parmtypes) == TREE_TYPE (typedecl))
+ TYPE_HAS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1;
+ }
+ }
+}
+
+/* Declare that every member function NAME in FRIEND_TYPE
+ (which may be NULL_TREE) is a friend of type TYPE. */
+
+static void
+add_friends (type, name, friend_type)
+ tree type, name, friend_type;
+{
+ tree typedecl = TYPE_MAIN_DECL (type);
+ tree list = DECL_FRIENDLIST (typedecl);
+
+ while (list)
+ {
+ if (name == TREE_PURPOSE (list))
+ {
+ tree friends = TREE_VALUE (list);
+ while (friends && TREE_PURPOSE (friends) != friend_type)
+ friends = TREE_CHAIN (friends);
+ if (friends)
+ if (friend_type)
+ warning ("method `%s::%s' is already a friend of class",
+ TYPE_NAME_STRING (friend_type),
+ IDENTIFIER_POINTER (name));
+ else
+ warning ("function `%s' is already a friend of class `%s'",
+ IDENTIFIER_POINTER (name),
+ IDENTIFIER_POINTER (DECL_NAME (typedecl)));
+ else
+ TREE_VALUE (list) = tree_cons (friend_type, NULL_TREE,
+ TREE_VALUE (list));
+ return;
+ }
+ list = TREE_CHAIN (list);
+ }
+ DECL_FRIENDLIST (typedecl)
+ = tree_cons (name,
+ build_tree_list (friend_type, NULL_TREE),
+ DECL_FRIENDLIST (typedecl));
+ if (! strncmp (IDENTIFIER_POINTER (name),
+ IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]),
+ strlen (IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]))))
+ {
+ TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
+ sorry ("declaring \"friend operator =\" will not find \"operator = (X&)\" if it exists");
+ }
+}
+
+/* Make FRIEND_TYPE a friend class to TYPE. If FRIEND_TYPE has already
+ been defined, we make all of its member functions friends of
+ TYPE. If not, we make it a pending friend, which can later be added
+ when its definition is seen. If a type is defined, then its TYPE_DECL's
+ DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend
+ classes that are not defined. If a type has not yet been defined,
+ then the DECL_WAITING_FRIENDS contains a list of types
+ waiting to make it their friend. Note that these two can both
+ be in use at the same time! */
+
+void
+make_friend_class (type, friend_type)
+ tree type, friend_type;
+{
+ tree classes;
+
+ if (IS_SIGNATURE (type))
+ {
+ error ("`friend' declaration in signature definition");
+ return;
+ }
+ if (IS_SIGNATURE (friend_type))
+ {
+ error ("signature type `%s' declared `friend'",
+ IDENTIFIER_POINTER (TYPE_IDENTIFIER (friend_type)));
+ return;
+ }
+ if (type == friend_type)
+ {
+ pedwarn ("class `%s' is implicitly friends with itself",
+ TYPE_NAME_STRING (type));
+ return;
+ }
+
+ GNU_xref_hier (TYPE_NAME_STRING (type),
+ TYPE_NAME_STRING (friend_type), 0, 0, 1);
+
+ classes = CLASSTYPE_FRIEND_CLASSES (type);
+ while (classes && TREE_VALUE (classes) != friend_type)
+ classes = TREE_CHAIN (classes);
+ if (classes)
+ warning ("class `%s' is already friends with class `%s'",
+ TYPE_NAME_STRING (TREE_VALUE (classes)), TYPE_NAME_STRING (type));
+ else
+ {
+ CLASSTYPE_FRIEND_CLASSES (type)
+ = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
+ }
+}
+
+/* Main friend processor. This is large, and for modularity purposes,
+ has been removed from grokdeclarator. It returns `void_type_node'
+ to indicate that something happened, though a FIELD_DECL is
+ not returned.
+
+ CTYPE is the class this friend belongs to.
+
+ DECLARATOR is the name of the friend.
+
+ DECL is the FUNCTION_DECL that the friend is.
+
+ In case we are parsing a friend which is part of an inline
+ definition, we will need to store PARM_DECL chain that comes
+ with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL.
+
+ FLAGS is just used for `grokclassfn'.
+
+ QUALS say what special qualifies should apply to the object
+ pointed to by `this'. */
+
+tree
+do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
+ tree ctype, declarator, decl, parmdecls;
+ enum overload_flags flags;
+ tree quals;
+ int funcdef_flag;
+{
+ /* Every decl that gets here is a friend of something. */
+ DECL_FRIEND_P (decl) = 1;
+
+ if (ctype)
+ {
+ tree cname = TYPE_NAME (ctype);
+ if (TREE_CODE (cname) == TYPE_DECL)
+ cname = DECL_NAME (cname);
+
+ /* A method friend. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (flags == NO_SPECIAL && ctype && declarator == cname)
+ DECL_CONSTRUCTOR_P (decl) = 1;
+
+ /* This will set up DECL_ARGUMENTS for us. */
+ grokclassfn (ctype, cname, decl, flags, quals);
+ if (TYPE_SIZE (ctype) != 0)
+ decl = check_classfn (ctype, decl);
+
+ if (TREE_TYPE (decl) != error_mark_node)
+ {
+ if (TYPE_SIZE (ctype))
+ add_friend (current_class_type, decl);
+ else
+ {
+ cp_error ("member `%D' declared as friend before type `%T' defined",
+ decl, ctype);
+ }
+ }
+ }
+ else
+ {
+ /* Possibly a bunch of method friends. */
+
+ /* Get the class they belong to. */
+ tree ctype = IDENTIFIER_TYPE_VALUE (cname);
+ tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0);
+
+ if (fields)
+ add_friends (current_class_type, declarator, ctype);
+ else
+ error ("method `%s' is not a member of class `%s'",
+ IDENTIFIER_POINTER (declarator),
+ IDENTIFIER_POINTER (cname));
+ decl = void_type_node;
+ }
+ }
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ && ((IDENTIFIER_LENGTH (declarator) == 4
+ && IDENTIFIER_POINTER (declarator)[0] == 'm'
+ && ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
+ || (IDENTIFIER_LENGTH (declarator) > 10
+ && IDENTIFIER_POINTER (declarator)[0] == '_'
+ && IDENTIFIER_POINTER (declarator)[1] == '_'
+ && strncmp (IDENTIFIER_POINTER (declarator)+2,
+ "builtin_", 8) == 0)))
+ {
+ /* raw "main", and builtin functions never gets overloaded,
+ but they can become friends. */
+ add_friend (current_class_type, decl);
+ DECL_FRIEND_P (decl) = 1;
+ decl = void_type_node;
+ }
+ /* A global friend.
+ @@ or possibly a friend from a base class ?!? */
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ /* Friends must all go through the overload machinery,
+ even though they may not technically be overloaded.
+
+ Note that because classes all wind up being top-level
+ in their scope, their friend wind up in top-level scope as well. */
+ DECL_ASSEMBLER_NAME (decl)
+ = build_decl_overload (declarator, TYPE_ARG_TYPES (TREE_TYPE (decl)),
+ TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE);
+ DECL_ARGUMENTS (decl) = parmdecls;
+ if (funcdef_flag)
+ DECL_CLASS_CONTEXT (decl) = current_class_type;
+
+ if (! DECL_USE_TEMPLATE (decl))
+ {
+ /* We can call pushdecl here, because the TREE_CHAIN of this
+ FUNCTION_DECL is not needed for other purposes. Don't do this
+ for a template instantiation. */
+ decl = pushdecl (decl);
+
+ if (! funcdef_flag && ! flag_guiding_decls
+ && current_template_parms && uses_template_parms (decl))
+ {
+ static int explained;
+ cp_warning ("friend declaration `%#D'", decl);
+ warning (" will not be treated as a template instantiation");
+ if (! explained)
+ {
+ warning (" unless you compile with -fguiding-decls");
+ warning (" or add <> after the function name");
+ explained = 1;
+ }
+ }
+ }
+
+ make_decl_rtl (decl, NULL_PTR, 1);
+ add_friend (current_class_type, decl);
+
+ DECL_FRIEND_P (decl) = 1;
+ }
+ else
+ {
+ /* @@ Should be able to ingest later definitions of this function
+ before use. */
+ tree decl = lookup_name_nonclass (declarator);
+ if (decl == NULL_TREE)
+ {
+ warning ("implicitly declaring `%s' as struct",
+ IDENTIFIER_POINTER (declarator));
+ decl = xref_tag (record_type_node, declarator, NULL_TREE, 1);
+ decl = TYPE_MAIN_DECL (decl);
+ }
+
+ /* Allow abbreviated declarations of overloaded functions,
+ but not if those functions are really class names. */
+ if (TREE_CODE (decl) == TREE_LIST && TREE_TYPE (TREE_PURPOSE (decl)))
+ {
+ warning ("`friend %s' archaic, use `friend class %s' instead",
+ IDENTIFIER_POINTER (declarator),
+ IDENTIFIER_POINTER (declarator));
+ decl = TREE_TYPE (TREE_PURPOSE (decl));
+ }
+
+ if (TREE_CODE (decl) == TREE_LIST)
+ add_friends (current_class_type, TREE_PURPOSE (decl), NULL_TREE);
+ else
+ make_friend_class (current_class_type, TREE_TYPE (decl));
+ decl = void_type_node;
+ }
+ return decl;
+}
diff --git a/gnu/usr.bin/gcc/cp/g++FAQ.texi b/gnu/usr.bin/gcc/cp/g++FAQ.texi
new file mode 100644
index 00000000000..f0064f346b1
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/g++FAQ.texi
@@ -0,0 +1,2158 @@
+\input texinfo.tex @c -*-texinfo-*-
+@c %**start of header
+@setfilename g++FAQ.info
+@settitle Frequently asked questions about the GNU C++ compiler
+@setchapternewpage off
+@c version: @(#)g++FAQ.texi 1.56 09/15/97
+@c %**end of header
+
+@iftex
+@finalout
+@end iftex
+@titlepage
+@title G++ FAQ
+@subtitle Frequently asked questions about the GNU C++ compiler
+@subtitle September 14, 1997
+@sp 1
+@author Joe Buck
+@page
+@end titlepage
+
+@ifinfo
+@node Top, basics, (dir), (dir)
+@top
+@unnumbered FAQ for g++ and libg++, by Joe Buck (jbuck@@synopsys.com)
+@end ifinfo
+
+@cindex FAQ for g++, latest version
+@cindex Archive site for FAQ lists
+@cindex rtfm.mit.edu
+@cindex Joe Buck <jbuck@@synopsys.com>
+@cindex FAQ for C++
+
+This is a list of frequently asked questions (FAQ) for g++ users; thanks to
+all those who sent suggestions for improvements. Thanks to Marcus Speh
+for doing the index. A hypertext version is available on the World Wide
+Web at @file{http://www.cygnus.com/misc/g++FAQ_toc.html}.
+
+This document has just been reorganized a bit. There is some new
+information about upcoming g++ releases and egcs; more needs to be done
+but that will need to wait for next time. A diff would look misleadingly
+large, since I blew away and rebuilt the texinfo menus.
+
+Please send updates and corrections to the FAQ to
+@code{jbuck@@synopsys.com}. Please do @emph{not} use me as a resource
+to get your questions answered; that's what @file{gnu.g++.help} is for and I
+don't have the time to support the net's use of g++.
+
+Many FAQs, including this one, are available on the archive site
+``rtfm.mit.edu''; see @*
+@file{ftp://rtfm.mit.edu/pub/usenet/news.answers}.
+This FAQ may be found in the subdirectory g++-FAQ.
+
+@cindex Marshall Cline
+@cindex comp.lang.c++
+@cindex C++ FAQ
+This FAQ is intended to supplement, not replace, Marshall Cline's
+excellent FAQ for the C++ language and for the newsgroup
+@file{comp.lang.c++}. Especially if g++ is the first C++
+compiler you've ever used, the question ``How do I do <X> with g++?''
+is probably really ``How do I do <X> in C++?''.
+You can find this FAQ at
+@file{ftp://rtfm.mit.edu/pub/usenet/comp.lang.c++},
+or in HTML form at @file{http://www.cerfnet.com/~mpcline/On-Line-C++-FAQs/}.
+
+@menu
+* basics:: What is g++? How do I get it?
+* installation:: How to install, installation problems
+* evolution:: The Evolution of g++
+* User Problems:: Commonly reported problems and bugs
+* legalities:: Lawyer stuff, GPL, LGPL, etc.
+* index:: Index of terms
+
+ --- The Detailed Node Listing ---
+
+The basics: what is g++?
+
+* latest versions::
+* g++ for Unix::
+* g++ for HP::
+* g++ for Solaris 2.x::
+* g++ for other platforms::
+* 1.x vs 2.x versions::
+
+Installation Issues and Problems
+
+* gcc-2 + g++-1::
+* what else do I need?::
+* use GNU linker?::
+* Use GNU assembler?::
+* shared libraries::
+* repository::
+* repo bugs::
+* Use GNU C library?::
+* Global constructor problems::
+* Strange assembler errors::
+* Other problems building libg++::
+* More size_t problems::
+* Rebuild libg++?::
+* co-existing versions::
+* Installing on Linux::
+* Linux Slackware 3.0::
+
+The Evolution of g++
+
+* version 2.7.x::
+* libstdc++::
+* new work::
+* egcs::
+* When?::
+
+User Problems
+
+* missing virtual table::
+* for scope::
+* const constructor::
+* unused parameter warnings::
+* jump crosses initialization::
+* Demangler::
+* static data members::
+* internal compiler error::
+* bug reports::
+* porting to g++::
+* name mangling::
+* problems linking with other libraries::
+* documentation::
+* templates::
+* undefined templates::
+* redundant templates::
+* Standard Template Library::
+* STL and string::
+* exceptions::
+* namespaces::
+* agreement with standards::
+* compiling standard libraries::
+* debugging on SVR4 systems::
+* debugging problems on Solaris::
+* X11 conflicts with libg++::
+* assignment to streams::
+@end menu
+
+@node basics, installation, Top, Top
+@chapter The basics: what is g++?
+
+@cindex Free Software Foundation
+@cindex GNU Public License
+@cindex GPL
+
+g++ is the traditional nickname of GNU C++, a freely redistributable
+C++ compiler produced by the Free Software Foundation plus dozens of
+skilled volunteers. I say ``traditional nickname'' because the GNU
+compiler suite, gcc, bundles together compilers for C, Objective-C,
+and C++ in one package.
+
+While the source code to gcc/g++ can be downloaded for free,
+it is not public domain, but is protected by the GNU Public License,
+or GPL (@pxref{legalities}).
+
+@menu
+* latest versions::
+* g++ for Unix::
+* g++ for HP::
+* g++ for Solaris 2.x::
+* g++ for other platforms::
+* 1.x vs 2.x versions::
+@end menu
+
+@node latest versions, g++ for Unix, basics, basics
+@section What is the latest version of gcc, g++, and libg++?
+
+@cindex gcc/g++, version date
+The current version of gcc/g++ is 2.7.2.3, released August 20, 1997.
+Although that looks very recent, the only change is a minor patch to
+resolve a problem with Linux and the GNU C library; users not interested
+in that functionality have no reason to upgrade.
+
+The current version of libg++ is 2.7.2, released July 4, 1996.
+The last release of gcc/g++ with improvements to the C++ front end was
+2.7.2, released Nov. 25, 1995, nearly two years ago.
+
+I would strongly recommend that anyone using a g++ version earlier
+than 2.7.2 should upgrade if at all possible (@pxref{version 2.7.x}).
+
+For some non-Unix platforms, the latest port of gcc may be an earlier
+version (2.6.3, say). You'll need to use a version of libg++ that
+has the same first two digits as the compiler version, e.g. use libg++
+2.6.x (for the latest x you can find) with gcc version 2.6.3.
+
+The latest "1.x" version of gcc is 1.42, and the latest "1.x" version of
+g++ is 1.42.0.
+While gcc 1.42 is quite usable for C programs,
+I recommend against using g++ 1.x except in special circumstances
+(and I can't think of any such circumstances).
+
+@node g++ for Unix, g++ for HP, latest versions, basics
+@section How do I get a copy of g++ for Unix?
+
+First, you may already have it if you have gcc for your platform;
+g++ and gcc are combined now (as of gcc version 2.0).
+@cindex GNU gcc, version
+@cindex GNU g++ and gcc
+
+You can get g++ from a friend who has a copy, by anonymous FTP or
+UUCP, or by ordering a tape or CD-ROM from the Free Software
+Foundation.
+@cindex g++, ordering
+@cindex g++, getting a copy
+
+The Free Software Foundation is a nonprofit organization that
+distributes software and manuals to raise funds for more GNU
+development. Getting your copy from the FSF contributes directly to
+paying staff to develop GNU software. CD-ROMs cost $400 if an
+organization is buying, or $100 if an individual is buying. Tapes
+cost around $200 depending on media type. I recommend asking for
+version 2, not version 1, of g++.
+@cindex FSF [Free Software Foundation]
+@cindex GNU [GNU's not unix]
+
+For more information about ordering from the FSF, contact
+gnu@@prep.ai.mit.edu, phone (617) 542-5942 or anonymous ftp file
+@file{ftp://prep.ai.mit.edu/pub/gnu/GNUinfo/ORDERS} (you can
+also use one of the sites listed below if you can't get into ``prep'').
+
+@cindex FSF, contact <gnu@@prep.ai.mit.edu>
+
+Here is a list of anonymous FTP archive sites for GNU software.
+If no directory is given, look in @file{/pub/gnu}.
+
+@cindex GNUware, anonymous FTP sites
+
+@example
+ASIA: ftp.cs.titech.ac.jp, tron.um.u-tokyo.ac.jp:/pub/GNU/prep
+cair-archive.kaist.ac.kr, ftp.nectec.or.th:/pub/mirrors/gnu
+
+AUSTRALIA: archie.au:/gnu (archie.oz or archie.oz.au for ACSnet)
+
+AFRICA: ftp.sun.ac.za
+
+MIDDLE-EAST: ftp.technion.ac.il:/pub/unsupported/gnu
+
+EUROPE: irisa.irisa.fr, ftp.univ-lyon1.fr,
+ftp.mcc.ac.uk, unix.hensa.ac.uk:/mirrors/uunet/systems/gnu,
+src.doc.ic.ac.uk:/gnu, ftp.ieunet.ie, ftp.eunet.ch,
+nic.switch.ch:/mirror/gnu, ftp.informatik.rwth-aachen.de,
+ftp.informatik.tu-muenchen.de, ftp.win.tue.nl, ftp.nl.net,
+ftp.etsimo.uniovi.es, ftp.funet.fi, ftp.denet.dk,
+ftp.stacken.kth.se, isy.liu.se, ftp.luth.se:/pub/unix/gnu,
+ftp.sunet.se, archive.eu.net
+
+SOUTH AMERICA: ftp.inf.utfsm.cl, ftp.unicamp.br
+
+WESTERN CANADA: ftp.cs.ubc.ca:/mirror2/gnu
+
+USA: wuarchive.wustl.edu:/systems/gnu, labrea.stanford.edu,
+ftp.digex.net, ftp.kpc.com:/pub/mirror/gnu, f.ms.uky.edu:/pub3/gnu,
+jaguar.utah.edu:/gnustuff, ftp.hawaii.edu:/mirrors/gnu,
+uiarchive.cso.uiuc.edu, ftp.cs.columbia.edu:/archives/gnu/prep,
+gatekeeper.dec.com:/pub/GNU, ftp.uu.net:/systems/gnu
+@end example
+
+The ``official site'' is prep.ai.mit.edu, but your transfer will probably
+go faster if you use one of the above machines.
+
+@cindex gzip
+Most GNU utilities are compressed with ``gzip'', the GNU compression
+utility. All GNU archive sites should have a copy of this program,
+which you will need to uncompress the distributions.
+
+@cindex libg++
+Don't forget to retrieve libg++ as well!
+
+@node g++ for HP, g++ for Solaris 2.x, g++ for Unix, basics
+@section Getting gcc/g++ for the HP Precision Architecture
+
+@cindex HP Precision Architecture
+@cindex Hewlett-Packard
+@cindex GNU GAS
+@cindex GNU gdb
+
+If you use the HP Precision Architecture (HP-9000/7xx and HP-9000/8xx)
+and you want to use debugging, you'll need to use the GNU assembler, GAS
+(version 2.3 or later). If you build from source, you must tell the
+configure program that you are using GAS or you won't get debugging
+support. A non-standard debug format is used, since until recently HP
+considered their debug format a trade secret. Thanks to the work of
+lots of good folks both inside and outside HP, the company has seen the
+error of its ways and has now released the required information. The
+team at the University of Utah that did the gcc port now has code that
+understands the native HP format.
+
+There are binaries for GNU tools in
+@file{ftp://jaguar.cs.utah.edu/dist/},
+but these are older versions.
+
+Jeff Law has left the University of Utah, so the Utah prebuilt
+binaries may be discontinued.
+
+@node g++ for Solaris 2.x, g++ for other platforms, g++ for HP, basics
+@section Getting gcc/g++ binaries for Solaris 2.x
+
+``Sun took the C compiler out of Solaris 2.x. Am I stuck?''
+
+@cindex Solaris
+@cindex gcc/g++ binaries for Solaris
+
+You'll need to get prebuilt binaries from someone.
+
+It used to be that you could get GCC binaries from prep.ai.mit.edu;
+these are no longer there.
+
+@cindex Solaris pkgadd utility
+The WWW site @file{http://smc.vnet.net/solaris_2.5.html}
+contains various
+GNU and freeware programs for Solaris2.5 running on the sparc. These are
+packaged to enable easy installation using the Solaris ``pkgadd'' utility.
+These include GNU emacs, gcc, gdb, perl, and others. These versions
+are more recent than the binaries at ``prep'' (gcc 2.7.2 and libg++
+2.7.1 are there).
+
+@node g++ for other platforms, 1.x vs 2.x versions, g++ for Solaris 2.x, basics
+@section How do I get a copy of g++ for (some other platform)?
+
+@cindex Windows NT support
+As of gcc-2.7.x, there is Windows NT support in gcc. Some special
+utilities are required. See the INSTALL file from the distribution.
+If you're interested in GNU tools on Windows NT, see
+@file{http://www.cygnus.com/misc/gnu-win32/} on the WWW, or the
+anonymous FTP directory
+@file{ftp://ftp.cygnus.com/pub/gnu-win32/}.
+
+@cindex VMS support
+@cindex VAX
+@cindex VMS, g++/libg++ precompiled
+
+The standard gcc/g++ distribution includes VMS support for the Vax.
+Since the FSF people don't use VMS, it's likely to be somewhat less
+solid than the Unix version. Precompiled copies of g++ and libg++ in
+VMS-installable form for the Vax are available by FTP from
+@file{ftp://mango.rsmas.miami.edu/pub/VMS-gcc/}.
+
+@cindex OpenVMS/Alpha
+Klaus Kaempf (kkaempf@@progis.de)
+has done a port to OpenVMS for the Alpha; this is not yet a
+part of the official gcc/g++.
+The port includes g++ and all libraries from the libg++ distribution. See
+@file{http://www.progis.de} for more details.
+
+@cindex MS-DOS support
+@cindex Delorie's gcc/g++
+@cindex DJGPP
+@cindex EMX
+There are two different versions of gcc/g++ for MS-DOS: EMX and DJGPP.
+EMX also works for OS/2 and is described later.
+DJGPP is DJ Delorie's port. It can be found on many FTP archive
+sites; try
+@file{ftp://ftp.coast.net/SimTel/vendors/djgpp/}
+or, for a complete list, see
+@file{http://www.delorie.com/djgpp/getting.html}.
+
+
+The latest version of DJGPP is 2.00. See
+@file{http://www.delorie.com/djgpp/v2/} for information on this version.
+
+FSF sells floppies with DJGPP on them; see above for ordering software
+from the FSF.
+
+DJGPP has its own newsgroup: @file{comp.os.msdos.djgpp}.
+
+@cindex Amiga support
+Development and porting efforts for GNU tools, including gcc/g++, for
+the Amiga are maintained by an initiative named ADE (Amiga Developers
+Environment. More information about ADE is available at
+@file{http://www.ninemoons.com/}.
+
+For more information on Amiga ports of gcc/g++, retrieve the file
+@file{ftp://prep.ai.mit.edu/pub/gnu/MicrosPorts/Amiga}.
+
+@cindex Atari ST support
+A port of gcc to the Atari ST can be found at @*
+@file{ftp://atari.archive.umich.edu/atari/Gnustuff/Tos}
+along with many
+other GNU programs. This version is usually the same as the latest FSF
+release. See the ``Software FAQ'' for the Usenet group
+@file{comp.sys.atari.st} for more information.
+
+@cindex EMX port
+@cindex OS/2 support
+
+EMX is a port of gcc to OS/2; it can also be used on MS-DOS. In addition to
+the compiler port, the EMX port's C library attempts to provide a
+Unix-like environment. For more information ask around on
+@file{comp.os.os2.programmer.porting}. Version 0.9c, based on gcc-2.7.2.1,
+was released in
+November 1996. It is available by FTP and the WWW from, among other
+places
+
+@example
+@file{http://www.os2ss.com/unix/emx09c/}
+@file{ftp://ftp.cdrom.com/pub/os2/emx09c/} (US)
+@file{ftp://ftp.leo.org/pub/comp/os/os2/leo/devtools/emx+gcc/} (Germany)
+@end example
+
+Eberhard Mattes did the EMX port. His address is
+mattes@@azu.informatik.uni-stuttgart.de.
+Read the FAQ file included with the distribution before harassing the author.
+
+@cindex Apple support
+@cindex Macintosh support
+
+I'm looking for more information on gcc/g++ support on the Apple
+Macintosh. Until recently, this FAQ did not provide such information,
+but FSF is no longer boycotting Apple as the League for Programming
+Freedom boycott has been dropped.
+
+Versions 1.37.1 and 2.3.3 of gcc were ported by Stan Shebs and are available
+at @*
+@file{ftp://ftp.cygnus.com/pub/mac}
+
+They are both interfaced to MPW.
+Stan is working on a version using the current (post-2.7) sources, contact
+him directly (shebs@@cygnus.com) for more information.
+
+@node 1.x vs 2.x versions, , g++ for other platforms, basics
+@section But I can only find g++-1.42!
+
+``I keep hearing people talking about g++ 2.7.2 (or some other number
+starting with 2), but the latest version I can find is g++ 1.42.
+Where is it?''
+
+@cindex Objective-C
+@cindex g++, version number
+As of gcc 2.0, C, C++, and Objective-C as well are all combined into a
+single distribution called gcc. If you get gcc you already have g++. The
+standard installation procedure for any gcc version 2 compiler will
+install the C++ compiler as well.
+
+One could argue that we shouldn't even refer to "g++-2.x.y" but it's a
+convention. It means ``the C++ compiler included with gcc-2.x.y.''
+
+@node installation, evolution, basics, Top
+@chapter Installation Issues and Problems
+
+@menu
+* gcc-2 + g++-1::
+* what else do I need?::
+* use GNU linker?::
+* Use GNU assembler?::
+* shared libraries::
+* repository::
+* repo bugs::
+* Use GNU C library?::
+* Global constructor problems::
+* Strange assembler errors::
+* Other problems building libg++::
+* More size_t problems::
+* Rebuild libg++?::
+* co-existing versions::
+* Installing on Linux::
+* Linux Slackware 3.0::
+@end menu
+
+@node gcc-2 + g++-1, what else do I need?, installation, installation
+@section I can't build g++ 1.x.y with gcc-2.x.y!
+
+``I obtained gcc-2.x.y and g++ 1.x.y and I'm trying to build it, but
+I'm having major problems. What's going on?''
+
+@cindex g++, building
+If you wish to build g++-1.42, you must obtain gcc-1.42 first. The
+installation instructions for g++ version 1 leave a lot to be desired,
+unfortunately, and I would recommend that, unless you have a special
+reason for needing the 1.x compiler, that C++ users use the latest
+g++-2.x version, as it
+is the version that is being actively maintained.
+
+@cindex g++, template support
+@cindex Templates
+@cindex ANSI draft standard
+There is no template support in g++-1.x, and it is generally much further
+away from the ANSI draft standard than g++-2.x is.
+
+@node what else do I need?, use GNU linker?, gcc-2 + g++-1, installation
+@section OK, I've obtained gcc; what else do I need?
+
+@cindex libg++
+First off, you'll want libg++ as you can do almost nothing without it
+(unless you replace it with some other class library).
+
+@cindex GNU GAS
+@cindex GNU GAS [assembler]
+Second, depending on your platform, you may need "GAS", the GNU assembler,
+or the GNU linker (see next question).
+
+@cindex GNU gdb
+Finally, while it is not required, you'll almost certainly want the GNU
+debugger, gdb. The latest version is
+4.16, released April 22, 1996.
+Other debuggers (like dbx, for example) will normally not be able to
+understand at least some of the debug information produced by g++.
+
+@node use GNU linker?, Use GNU assembler?, what else do I need?, installation
+@section Should I use the GNU linker, or should I use "collect"?
+
+@cindex Linker
+@cindex System VR3, linker
+@cindex System VR4, linker
+First off, for novices: special measures must be taken with C++ to arrange
+for the calling of constructors for global or static objects before the
+execution of your program, and for the calling of destructors at the end.
+(Exception: System VR3 and System VR4 linkers, Linux/ELF, and some other
+systems support user-defined
+segments; g++ on these systems requires neither the GNU linker nor
+collect. So if you have such a system, the answer is that you don't
+need either one, though using GNU ld does have some advantages over
+the native linker in some cases).
+
+@cindex AT&T cfront
+@cindex Cfront-end
+@cindex collect program
+@cindex GNU linker
+@cindex GNU binutils
+If you have experience with AT&T's "cfront", this function is performed
+there by programs named "patch" or "munch". With GNU C++, it is performed
+either by the GNU linker or by a program known as "collect". The collect
+program is part of the gcc-2.x distribution; you can obtain the GNU linker
+separately as part of the "binutils" package. The latest version of
+binutils is 2.7, released July 10, 1996; 2.6 is in common use and works
+well.
+
+(To be technical, it's "collect2"; there were originally several
+alternative versions of collect, and this is the one that survived).
+
+There are advantages and disadvantages to either choice.
+
+Advantages of the GNU linker:
+@cindex GNU linker, advantages
+@cindex GNU ld
+@cindex ld [GNU linker]
+
+It's faster than using collect -- collect basically runs the standard Unix
+linker on your program twice, inserting some extra code after the first
+pass to call the constructors. This is a sizable time penalty for large
+programs. The GNU linker does not require this extra pass.
+
+GNU ld reports undefined symbols using their true names, not the mangled
+names (but as of 2.7.0 so does collect).
+
+If there are undefined symbols, GNU ld reports which object file(s) refer to
+the undefined symbol(s). On some OSes (e.g. SunOS, Solaris) the native
+linker does not do this, so you have to track down who's referring to
+the missing symbols yourself.
+
+As of binutils version 2.2, on systems that use the so-called "a.out"
+debug format (e.g. Suns running SunOS 4.x), the GNU linker compresses
+the debug symbol table considerably. The 2.7 version adds some symbol
+table compression for ELF and Solaris targets.
+
+@cindex collect linker, advantages
+Advantages of collect:
+
+@cindex Shared libraries
+If your native linker supports shared libraries, you can use shared
+libraries with collect. This used to be a strong reason @emph{not}
+to use the GNU linker, but recent versions of GNU ld support linking
+with shared libraries on many platforms, and creating shared libraries
+on a few (such as Intel x86 systems that use ELF object format as well
+as SunOS and Solaris).
+
+@xref{shared libraries}
+
+@cindex GNU linker, porting
+The GNU linker has not been ported to as many platforms as g++ has, so you
+may be forced to use collect.
+
+If you use collect, you don't need to get something extra and figure out
+how to install it; the standard gcc installation procedure will do it for you.
+
+I used to say at this point that I don't see a clear win for either
+linking alternative, but with all the improvements in the GNU linker
+I think that it is now the better choice. Take your pick.
+
+If you run Linux, the only available linker is the GNU linker.
+
+@node Use GNU assembler?, shared libraries, use GNU linker?, installation
+@section Should I use the GNU assembler, or my vendor's assembler?
+
+@cindex Assembler
+@cindex GNU GAS
+This depends on your platform and your decision about the GNU linker. For
+most platforms, you'll need to use GAS if you use the GNU linker. For
+some platforms, you have no choice; check the gcc installation notes to
+see whether you must use GAS. But you can usually use the vendor's
+assembler if you don't use the GNU linker.
+
+The GNU assembler assembles faster than many native assemblers; however,
+on many platforms it cannot support the local debugging format.
+
+It used to be that the GNU assembler couldn't handle
+position-independent code on SunOS. This is no longer true if you
+have version 2.6 or newer.
+
+On HPUX or IRIX, you must use GAS (and configure gcc with the
+@code{--with-gnu-as} option) to debug your programs. GAS is
+strongly recommended particularly on the HP platform because of
+limitations in the HP assembler.
+
+The GNU assembler has been merged with the binutils
+distribution, so the GNU assembler and linker are now together in
+this package (as of binutils version 2.5.1).
+
+On Linux the assembler is the GNU assembler.
+
+@node shared libraries, repository, Use GNU assembler?, installation
+@section How do I build shared libraries with g++?
+
+For gcc-2.7.0 and later, building C++ shared libraries should work fine
+on supported platforms (HPUX 9+, IRIX 5+, DEC UNIX (formerly OSF/1),
+SGI/IRIX, AIX, SunOS 4, Linux/ELF and all targets using SVR4-style ELF shared
+libraries). There are two separate issues: building libg++ as a shared
+library, and making your own shared libraries. For libg++ it is simply
+a matter of giving the @code{--enable-shared} option to the configure
+program. When compiling your own code for shared libraries you
+generally
+must use the @code{-fPIC} flag to get position-independent code.
+
+@cindex -shared flag of gcc
+
+If your shared library contains global or static objects with
+constructors, then make sure to use @code{gcc -shared}, not
+@code{ld}, to create the shared library. This will make sure
+that any processor-specific magic needed to execute the constructors
+is included.
+
+In theory, constructors for objects in your shared library should be
+called when the library is opened (by dlopen or equivalent). This
+does not work on some platforms (e.g. SunOS4; it does work on Solaris
+and ELF systems such as Linux): on the broken platforms, the
+constructors are not called correctly.
+
+David Nilsen has suggested the following workaround:
+
+The thing to realize is that if you link your dynamic module with the
+@code{-shared} flag, the collect program nicely groups all the static
+ctors/dtors for you into a list and sets up a function that will call
+them (Note: this means that this trick won't work if you use the GNU
+linker without collect (@pxref{use GNU linker?}).
+
+The magic is knowing these function names. Currently, they're called:
+
+@example
+_GLOBAL__DI <-- calls all module constructors
+_GLOBAL__DD <-- calls all module destructors
+@end example
+
+[ possibly the leading underscore will differ between platforms: jbuck ]
+
+Therefore, if you make a wrapper around dlopen that looks up the
+symbol @code{_GLOBAL__DI} (or @code{__GLOBAL__DI} on SunOS4 machines), and
+calls it, you'll simulate getting the constructors called.
+
+You also need to set up the destructors to be called as well, so you
+need to put a wrapper around dlclose, which will call the
+@code{_GLOBAL__DD} function in the module when/if it's unloaded.
+
+Lastly, to get things 100% correct, you need to set up the destructors
+to also be called if the module is not unloaded, but the main program
+exits. I do this by registering a single function with @code{atexit()} that
+calls all the destructors left in dynamically loaded modules.
+
+@cindex Shared version of libg++
+Check the file @file{README.SHLIB} from the libg++ distribution for more
+about making and using shared libraries.
+
+@cindex Shared libraries with HP
+
+A patch is needed to build shared versions of version 2.7.2 of libg++
+and libstdc++ on the HP-PA architecture. You can find the patch at
+@file{ftp://ftp.cygnus.com/pub/g++/libg++-2.7.2-hppa-gcc-fix}.
+
+@node repository, repo bugs, shared libraries, installation
+@section How do I use the new repository code?
+
+@cindex repo patch
+Because there is some disagreement about the details of the template
+repository mechanism, you'll need to obtain a patch from Cygnus Support
+to enable the 2.7.2 repository code. You can obtain the patch by
+anonymous FTP: @file{ftp://ftp.cygnus.com/pub/g++/gcc-2.7.2-repo.gz}.
+
+There are patches for 2.7.0 and 2.7.1 in the same directory, though
+if you're going to rebuild the compiler you should use the latest one.
+
+@cindex repo patch for BSD
+If you're running NetBSD or BSDI, the Cygnus repo patch is not quite
+correct. Tim Liddelow has made an alternate version available at
+@file{ftp://ftp.cst.com.au/pub/gcc-2.7.2-repo-bsd.gz}.
+
+After you've applied the patch, the @code{-frepo} flag will enable the
+repository mechanism. The flag works much like the existing
+@code{-fno-implicit-templates} flag, except that auxiliary files, with
+an @file{.rpo} extension, are built that specify what template
+expansions are needed. At link time, the (patched) collect program
+detects missing templates and recompiles some of the object files
+so that the required templates are expanded.
+
+Note that the mechanism differs from that of cfront in that template
+definitions still must be visible at the point where they are to be
+expanded. No assumption is made that @file{foo.C} contains template
+definitions corresponding to template declarations in @file{foo.h}.
+
+@cindex closure with repo
+@cindex template closure
+Jason Merrill writes: ``To perform closure on a set of objects, just try
+to link them together. It will fail, but as a side effect all needed
+instances will be generated in the objects.''
+
+@node repo bugs, Use GNU C library?, repository, installation
+@section Known bugs and problems with the repo patch
+
+``The @code{-frepo} won't expand templated friend functions!''
+
+This is a known bug; currently you'll have to explicitly instantiate
+friend functions when using @code{-frepo} due to this bug (in 2.7.0
+through 2.7.2 at least).
+
+With earlier versions of the repo patch, there was a bug that happens
+when you have given a quoted command line switch, something like
+
+@example
+-D'MESSAGE="hello there"'
+@end example
+
+The repo code tries to recompile files using the same flags you
+originally specified, but doesn't quote arguments that need quoting,
+resulting in failures in some cases. This is no longer a problem
+with the 2.7.2 patch.
+
+@node Use GNU C library?, Global constructor problems, repo bugs, installation
+@section Should I use the GNU C library?
+
+@cindex GNU C library
+@cindex libg++
+At this point in time, no (unless you are running Linux or the GNU Hurd
+system). The GNU C library is still very young, and
+libg++ still conflicts with it in some places. Use your native C library
+unless you know a lot about the gory details of libg++ and gnu-libc. This
+will probably change in the future.
+
+@node Global constructor problems, Strange assembler errors, Use GNU C library?, installation
+@section Global constructors aren't being called
+
+@cindex global constructors
+``I've installed gcc and it almost works, but constructors and
+destructors for global objects and objects at file scope aren't being
+called. What did I do wrong?''
+
+@cindex collect program
+It appears that you are running on a platform that requires you to
+install either "collect2" or the GNU linker, and you have done neither.
+For more information, see the section discussing the GNU linker
+(@pxref{use GNU linker?}).
+
+@cindex constructor problems on Solaris
+@cindex Solaris, constructor problems
+On Solaris 2.x, you shouldn't need a collect program and GNU ld doesn't run.
+If your global constructors aren't being called, you may need to install
+a patch, available from Sun, to fix your linker. The number of the
+``jumbo patch'' that applies is 101409-03. Thanks to Russell Street
+(r.street@@auckland.ac.nz) for this info.
+
+@cindex IRIX, installing collect
+It appears that on IRIX, the collect2 program is not being installed
+by default during the installation process, though it is required;
+you can install it manually by executing
+
+@example
+make install-collect2
+@end example
+
+from the gcc source directory after installing the compiler. (I'm
+not certain for which versions of gcc this problem occurs, and whether
+it is still present).
+
+@node Strange assembler errors, Other problems building libg++, Global constructor problems, installation
+@section Strange assembler errors when linking C++ programs
+
+``I've installed gcc and it seemed to go OK, but when I attempt to link
+any C++ program, I'm getting strange errors from the assembler! How
+can that be?''
+
+The messages in question might look something like
+
+@example
+as: "/usr/tmp/cca14605.s", line 8: error: statement syntax
+as: "/usr/tmp/cca14605.s", line 14: error: statement syntax
+@end example
+
+(on a Sun, different on other platforms). The important thing is that
+the errors come out at the link step, @emph{not} when a C++ file is
+being compiled.
+
+@cindex nm program
+@cindex GNU nm program
+Here's what's going on: the collect2 program uses the Unix ``nm''
+program to obtain a list of symbols for the global constructors and
+destructors, and it builds a little assembly language module that
+will permit them all to be called. If you're seeing this symptom,
+you have an old version of GNU nm somewhere on your path. This old
+version prints out symbol names in a format that the collect2 program
+does not expect, so bad assembly code is generated.
+
+The solution is either to remove the old version of GNU nm from your
+path (and that of everyone else who uses g++), or to install a newer
+version (it is part of the GNU "binutils" package). Recent versions
+of GNU nm do not have this problem.
+
+@node Other problems building libg++, More size_t problems, Strange assembler errors, installation
+@section Other problems building libg++
+@cindex libg++ on Ultrix
+@cindex libg++ on SunOS
+
+``I am having trouble building libg++. Help!''
+
+On some platforms (for example, Ultrix), you may see errors complaining
+about being unable to open dummy.o. On other platforms (for example,
+SunOS), you may see problems having to do with the type of size_t.
+The fix for these problems is to make libg++ by saying "make CC=gcc".
+According to Per Bothner, it should no longer be necessary to specify
+"CC=gcc" for libg++-2.3.1 or later.
+
+``I built and installed libg++, but g++ can't find it. Help!''
+
+The string given to @file{configure} that identifies your system must
+be the same when you install libg++ as it was when you installed gcc.
+Also, if you used the @code{--prefix} option to install gcc somewhere
+other than @file{/usr/local}, you must use the same value for
+@code{--prefix} when installing libg++, or else g++ will not be able
+to find libg++.
+
+@cindex patch for libg++-2.6.2
+
+The toplevel Makefile in the libg++ 2.6.2 distribution is broken, which
+along with a bug in g++ 2.6.3 causes problems linking programs that use the
+libstdc++ complex classes. A patch for this is available from
+@file{ftp://ftp.cygnus.com//pub/g++/libg++-2.6.2-fix.gz}.
+
+@node More size_t problems, Rebuild libg++?, Other problems building libg++, installation
+@section But I'm @emph{still} having problems with @code{size_t}!
+
+@cindex Type of size_t
+``I did all that, and I'm @emph{still} having problems with disagreeing
+definitions of size_t, SIZE_TYPE, and the type of functions like
+@code{strlen}.''
+
+@cindex _G_config.h
+The problem may be that you have an old version of @file{_G_config.h}
+lying around. As of libg++ version 2.4, @file{_G_config.h}, since it is
+platform-specific, is inserted into a different directory; most include
+files are in @file{$prefix/lib/g++-include}, but this file now lives in
+@file{$prefix/$arch/include}. If, after upgrading your libg++, you find that
+there is an old copy of @file{_G_config.h} left around, remove it,
+otherwise g++ will find the old one first.
+
+@node Rebuild libg++?, co-existing versions, More size_t problems, installation
+@section Do I need to rebuild libg++ to go with my new g++?
+
+``After I upgraded g++ to the latest version, I'm seeing undefined
+symbols.''
+
+or
+
+``If I upgrade to a new version of g++, do I need to reinstall libg++?''
+
+@cindex Incompatibilities between g++ versions
+
+As a rule, the first two digits of your g++ and libg++ should be the
+same. Normally when you do an upgrade in the ``minor version number''
+(2.5.7 to 2.5.8, say) there isn't a need to rebuild libg++, but there
+have been a couple of exceptions in the past.
+
+@node co-existing versions, Installing on Linux, Rebuild libg++?, installation
+@section I want several versions of g++ and libg++ to co-exist.
+
+I recommend against using the @code{-V} flag to make multiple versions
+of gcc/g++ co-exist, unless they are different minor releases that can use
+the same compiled version of libg++. The reason is that all these
+versions will try to use the same libg++ version, which usually will
+not work.
+
+Instead, use the @code{--prefix} flag when configuring gcc. Use a
+different value of @code{--prefix} for each gcc version. Use the
+same value of @code{--prefix} when configuring libg++. You can then
+have any number of co-existing gcc/libg++ pairs. Symbolic links can
+be used so that users don't need to put all these different directories
+on their paths.
+
+One possible system to use is to set @code{--prefix} to
+@file{/usr/local/gcc-2.x.y} for version 2.x.y of gcc, and to link
+whichever version of gcc you wish to be the default into
+@file{/usr/local/bin/gcc} and @file{/usr/local/bin/g++}.
+
+@node Installing on Linux, Linux Slackware 3.0, co-existing versions, installation
+@section Trouble installing g++ and libg++ on Linux
+
+``I've downloaded the latest g++ and libg++ and I'm trying to install
+them on Linux, and I'm having lots of problems.''
+
+@cindex Linux
+FSF releases of libg++ won't install on Linux unchanged, since Linux
+uses are part of the libio library from libg++ for its standard C
+library, only this is changed in a way that it clashes with libg++.
+This means that you'll need a patched version of libg++ for it to
+work.
+
+If you want to upgrade to a new gcc/libg++ combination, the easiest
+thing to do is to grab the prebuilt versions of gcc and libg++ for Linux
+from @file{ftp://tsx-11.mit.edu/pub/linux/packages/GCC}. Follow the
+directions carefully. If you want to build from source, you'll need
+a patch for libg++; the Linux developers have named the patched libg++
+version libg++-2.7.1.3 and there is a patch file in the above-named
+directory.
+
+See @file{http://sunsite.unc.edu/LDP/HOWTO/GCC-HOWTO.html},
+the Linux GCC HOWTO, for more on gcc/g++ and Linux.
+
+Linux is in the process of switching over to the GNU C library, version
+2, which will become Linux libc version 6. Once this process is
+complete, there's a good chance that the installation process on Linux
+will be smoother, but only experts should try making this new library
+work at this point.
+
+@node Linux Slackware 3.0, , Installing on Linux, installation
+@section Problems with g++ on Linux Slackware 3.0
+
+@cindex Slackware
+@cindex Linux Slackware
+``When I try to compile the traditional Hello, world program on Linux,
+the compiler can't find @file{iostream.h}. What's the deal?''
+
+You probably have the Slackware 3.0 release. There's an error in the
+setup. It's easy to fix, though; log in as root, and make a symbolic
+link:
+
+@example
+ln -s /usr/lib/g++-include /usr/include/g++
+@end example
+
+@node evolution, User Problems, installation, Top
+@chapter The Evolution of g++
+
+This chapter discusses the evolution of g++ and describes what can be expected
+in the future.
+
+@menu
+* version 2.7.x:: What's changed in 2.7.x from earlier versions
+* libstdc++:: The GNU C++ standard library
+* new work:: What's been done since 2.7.x
+* egcs:: The Experimental GNU Compiler System
+* When?:: When can I get all this new stuff?
+@end menu
+
+@node version 2.7.x, libstdc++, evolution, evolution
+@section What's new in version 2.7.x of gcc/g++
+
+The current version of gcc/g++ is 2.7.2.2, released February 10, 1997.
+The only change between 2.7.2.1 and 2.7.2.2 is that support was added
+for using the GNU C library, version 2, on Linux; users not interested
+in that functionality have no reason to upgrade.
+The previous version of gcc/g++ is 2.7.2.1, released August 14, 1996.
+The current version of libg++ is 2.7.2, released July 4, 1996.
+
+Note that gcc 2.7.2.1 just consists of several small patches to
+gcc-2.7.2. The release is mainly
+intended to fix platform-specific bugs and does not affect the C++
+``front end'' of the compiler (the part that parses your C++ code).
+
+The 2.7.x releases represent a great deal of work on the part of the g++
+maintainers to fix outstanding bugs and move the compiler closer to the
+current ANSI/ISO standards committee's working paper, including
+supporting many of the new features that have been added to the
+language. I recommend that everyone read the NEWS file contained in the
+distribution (and that system administrators make the file available to
+their users). I've borrowed liberally from this file here.
+
+@cindex C++ working paper
+If any features seem unfamiliar, you will probably want to
+look at the recently-released public review copy of the C++ Working
+Paper. A new draft, dated 2 December 1996, has been released for
+public comment. You can find it on the web at
+@file{http://www.cygnus.com/misc/wp/} or
+@file{http://www.maths.warwick.ac.uk/c++/pub/wp/html/cd2/}.
+See
+@file{http://www.setech.com/x3.html}
+or
+@file{http://www.maths.warwick.ac.uk/c++/pub/} to download the
+document in PostScript, PDF (Adobe Acrobat), HTML, or ASCII
+form.
+
+Here are the main points:
+
+@itemize @bullet
+@item
+@cindex for scope
+As described above, the scope of variables declared in the
+initialization part of a for statement has been changed; such variables
+are now visible only in the loop body. Use @code{-fno-for-scope} to get
+the old behavior. You'll need this flag to build groff version 1.09,
+Ptolemy, and many other free software packages.
+
+@item
+@cindex vtable duplication
+Code that does not use #pragma interface/implementation will most
+likely shrink dramatically, as g++ now only emits the vtable for a
+class in the translation unit where its first non-inline, non-abstract
+virtual function is defined.
+
+@item
+@cindex automatic template instantiation
+Support for automatic template instantiation has @emph{not} been enabled
+in the official distribution, due to a disagreement over design philosophies.
+But you can get a patch from Cygnus to turn it on; retrieve the patch
+from @file{ftp://ftp.cygnus.com/pub/g++/gcc-2.7.2-repo.gz} to patch
+gcc-2.7.2 (there are also patches for earlier gcc versions).
+
+@item
+@cindex exception handling, 2.7.0
+
+@xref{exceptions}
+
+@item
+@cindex run-time type identification
+Support for Run-Time Type Identification has been added with @code{-frtti}.
+This support is still in alpha; one major restriction is that any file
+compiled with @code{-frtti} must include @code{<typeinfo>} (@emph{not}
+@code{typeinfo.h} as the NEWS file says).
+Also, all C++ code you link with (including libg++) has to be built with
+@code{-frtti}, so it's still tricky to use.
+
+@item
+@cindex compiler-generated operators
+Synthesis of compiler-generated constructors, destructors and
+assignment operators is now deferred until the functions are used.
+
+@item
+@cindex assignment in conditional expressions
+The parsing of expressions such as @code{a ? b : c = 1}
+has changed from
+@code{(a ? b : c) = 1} to @code{a ? b : (c = 1)}. This is a new C/C++
+incompatibility brought to you by the ANSI/ISO standards committee.
+
+@item
+@cindex new operator keywords
+The operator keywords and, and_eq, bitand, bitor, compl, not, not_eq,
+or, or_eq, xor and xor_eq are now supported. Use @code{-ansi} or
+@code{-foperator-names} to enable them.
+
+@item
+@cindex explicit keyword
+The @code{explicit} keyword is now supported. @code{explicit} is used to mark
+constructors and type conversion operators that should not be used
+implicitly.
+
+@item
+@cindex user-defined type conversion
+Handling of user-defined type conversion has been improved.
+
+@item
+@cindex explicit template instantiation
+Explicit instantiation of template methods is now supported. Also,
+@code{inline template class foo<int>;}
+can be used to emit only the vtable
+for a template class.
+
+@item
+@cindex -fcheck-new
+With -fcheck-new, g++ will check the return value of all calls to
+operator new, and not attempt to modify a returned null pointer.
+
+@item
+collect2 now demangles linker output, and c++filt has become part of
+the gcc distribution.
+
+@item
+Improvements to template instantiation: only members actually used
+are instantiated. (Actually this is not quite true: some inline
+templates that are not successfully inlined may be expanded even
+though they are not needed).
+
+@end itemize
+
+@node libstdc++, new work, version 2.7.x, evolution
+@section The GNU Standard C++ Library
+
+The GNU Standard C++ Library (also called the ``GNU ANSI C++ Library''
+in places in the code) is not libg++, though it is included in the
+libg++ distribution. Rather, it contains classes and functions
+required by the ANSI/ISO standard. The copyright conditions are the
+same as those for for the iostreams classes; the LGPL is not used
+(@pxref{legalities}).
+
+This library, libstdc++, is in the libg++ distribution in versions 2.6.2
+and later. It requires at least gcc 2.6.3 to build the libg++-2.6.2
+version; use at least gcc 2.7.0 to build the libg++ 2.7.0 version. It
+contains a hacked-up version of HP's implementation of the Standard
+Template Library (@pxref{Standard Template Library}). I've
+successfully used this Standard Template Library version to build
+a number of the demos you'll see on various web pages.
+
+As of version 2.7.0, the streams classes are now in libstdc++ instead of
+libg++, and libiostream is being phased out (don't use it). The g++
+program searches this library.
+
+The maintainers of libg++ have de-emphasized work on the older libg++ classes
+in favor of enhancing libstdc++ to cover the full language, so while libg++
+will always be available, enhancements to it should not be expected.
+
+@node new work, egcs, libstdc++, evolution
+@section What can we expect in future gcc releases?
+
+A great deal of work has gone into enhancements to the C++ front end, as well
+as to other aspects of the compiler.
+
+The next major release(s) of gcc/g++ can be expected to have the following
+features:
+
+@itemize @bullet
+@cindex new template implementation
+@item
+A completely new template implementation, much closer to the draft
+standard. Limitations in 2.7.2.x concerning inlining template functions
+will be eliminated. Static template data members, template class member
+functions, partial specification, and default template arguments will be
+supported. An instantiation method resembling that used in Borland C++
+(instantiating functions possibly in multiple .o files and using weak
+symbols to link correctly) will be provided, in addition to other
+options. The SGI version of STL will be shipped with libstdc++ and will
+compile unchanged.
+
+@item
+@cindex new exception implementation
+Exception handling has been re-worked; exceptions will work together
+with optimization.
+Actually, there are two separate implementations: one based on setjmp/longjmp
+and designed to be highly portable, and one designed to be more efficient but
+requiring more processor-specific support (getting exceptions right has proven
+to be extremely difficult and has been the chief obstacle to getting a new
+release out).
+
+@item
+@cindex RTTI
+RTTI has been re-done to work correctly and is on by default.
+
+@item
+@cindex overloading
+Overloading has been re-worked to conform to the latest draft of the
+standard.
+@end itemize
+
+Features that are still missing include namespaces and templates as
+template arguments.
+
+@node egcs, When?, new work, evolution
+@section What's this I hear about egcs?
+
+The egcs effort is a new effort to merge several threads of gcc
+development and to provide a faster development process.
+For more information see @file{http://www.cygnus.com/egcs/}.
+
+@node When?, , egcs, evolution
+@section OK, when can I get this stuff?
+
+The FSF has a policy of never announcing release dates in advance.
+I'm sure this is frustrating to a lot of people, since it's taken
+so long, and this frustration was one of the reasons the egcs effort
+was created. An egcs release should be expected to occur in the
+very near future. [ More on this next time ].
+
+@node User Problems, legalities, evolution, Top
+@chapter User Problems
+
+@menu
+* missing virtual table::
+* for scope::
+* const constructor::
+* unused parameter warnings::
+* jump crosses initialization::
+* Demangler::
+* static data members::
+* internal compiler error::
+* bug reports::
+* porting to g++::
+* name mangling::
+* problems linking with other libraries::
+* documentation::
+* templates::
+* undefined templates::
+* redundant templates::
+* Standard Template Library::
+* STL and string::
+* exceptions::
+* namespaces::
+* agreement with standards::
+* compiling standard libraries::
+* debugging on SVR4 systems::
+* debugging problems on Solaris::
+* X11 conflicts with libg++::
+* assignment to streams::
+@end menu
+
+@node missing virtual table, for scope, User Problems, User Problems
+@section Linker complains about missing virtual table
+
+``I'm getting a message complaining about an undefined virtual table. Is
+this a compiler bug?''
+
+(On platforms that run neither collect nor the GNU linker, like Solaris,
+you may see an odd undefined symbol like "_vt.3foo", where foo is a
+class name).
+
+This is probably because you are missing a definition for the first
+(non-inline) virtual function of the class. Since gcc-2.7.0, g++ uses
+a trick borrowed from cfront: the .o file containing the definition for
+the first non-inline virtual function for the class will also contain
+the virtual function table.
+
+@node for scope, const constructor, missing virtual table, User Problems
+@section gcc-2.7.0 breaks declarations in "for" statements!
+
+@cindex declarations in for statements
+@cindex for statements: declarations
+
+gcc-2.7.0 implements the new ANSI/ISO rule on the scope of variables
+declared in for loops.
+
+@example
+for (int i = 1; i <= 10; i++) @{
+ // do something here
+@}
+foo(i);
+@end example
+
+In the above example, most existing C++ compilers would pass the
+value 11 to the function @code{foo}. In gcc 2.7 and in the ANSI/ISO
+working paper, the scope of @code{i} is only the for loop body, so
+this is an error. So that old code can be compiled, the new gcc has
+a flag @code{-fno-for-scope} that causes the old rule to be used.
+@cindex -fno-for-scope
+
+As of 2.7.1, the compiler attempts to issue warnings about code that
+has different meanings under the two sets of rules, but the code is
+not perfect: the intent was that code that has valid, but different,
+meanings under the ARM rules and the working paper rules would give
+warnings but have the new behavior, and this doesn't seem to happen.
+
+The @code{-ffor-scope} flag under 2.7.1 and 2.7.2 gives the 2.7.0 behavior.
+
+@node const constructor, unused parameter warnings, for scope, User Problems
+@section g++ seems to want a const constructor. What's that?
+
+gcc-2.7.1 introduced a bug that causes the compiler to ask for a
+const constructor (there's no such thing in C++) in certain situations
+where a const object appears in a template class. Most cases have been
+fixed in gcc-2.7.2, but unfortunately not all. Still, if you're running
+gcc-2.7.1 and have this problem, upgrade to 2.7.2; it is a vast improvement.
+
+@cindex ObjectSpace<STL>
+
+The default constructor for the template @code{pair} in ObjectSpace's
+implementation of STL triggers the bug in one place, for gcc 2.7.2. If
+you're using ObjectSpace<STL> and having this problem, simply
+change the default constructor from
+
+@example
+os_pair () : first (T1 ()), second (T2 ()) @{@}
+@end example
+
+to just
+
+@example
+os_pair () @{@}
+@end example
+
+Once this is done, ObjectSpace<STL> works fairly well.
+
+@node unused parameter warnings, jump crosses initialization, const constructor, User Problems
+@section How to silence ``unused parameter'' warnings
+
+@cindex -Wall
+@cindex -Wunused
+
+``When I use @code{-Wall} (or @code{-Wunused}), g++ warns about
+unused parameters. But the parameters have to be there, for use
+in derived class functions. How do I get g++ to stop complaining?''
+
+The answer is to simply omit the names of the unused parameters when
+defining the function. This makes clear, both to g++ and to readers
+of your code, that the parameter is unused. For example:
+
+@example
+int Foo::bar(int arg) @{ return 0; @}
+@end example
+
+will give a warning for the unused parameter @code{arg}. To suppress
+the warning write
+
+@example
+int Foo::bar(int) @{ return 0; @}
+@end example
+
+@node jump crosses initialization, Demangler, unused parameter warnings, User Problems
+@section g++ objects to a declaration in a case statement
+
+``The compiler objects to my declaring a variable in one of the branches
+of a case statement. Earlier versions used to accept this code. Why?''
+
+The draft standard does not allow a goto or a jump to a case label to
+skip over an initialization of a variable or a class object. For
+example:
+
+@example
+switch ( i ) @{
+ case 1:
+ Object obj(0);
+ ...
+ break;
+ case 2:
+ ...
+ break;
+@}
+@end example
+
+The reason is that @code{obj} is also in scope in the rest of the switch
+statement.
+
+As of version 2.7.0, the compiler will object that the jump to the
+second case level crosses the initialization of @code{obj}. Older
+compiler versions would object only if class Object has a destructor.
+In either case, the solution is to add a set of curly braces around
+the case branch:
+
+@example
+ case 1:
+ @{
+ Object obj(0);
+ ...
+ break;
+ @}
+@end example
+
+@node Demangler, static data members, jump crosses initialization, User Problems
+@section Where can I find a demangler?
+
+@cindex demangler program
+A g++-compatible demangler named @code{c++filt} can be found in the
+@file{binutils} distribution. This distribution (which also contains
+the GNU linker) can be found at any GNU archive site.
+
+As of version 2.7.0, @code{c++filt} is included with gcc and is
+installed automatically. Even better, it is used by the @code{collect}
+linker, so you don't see mangled symbols anymore (except on platforms
+that use neither collect nor the GNU linker, like Solaris).
+
+@node static data members, internal compiler error, Demangler, User Problems
+@section Linker reports undefined symbols for static data members
+
+@cindex Static data members
+``g++ reports undefined symbols for all my static data members when I link,
+even though the program works correctly for compiler XYZ. What's going on?''
+
+The problem is almost certainly that you don't give definitions for
+your static data members. If you have
+
+@example
+class Foo @{
+ ...
+ void method();
+ static int bar;
+@};
+@end example
+
+you have only declared that there is an int named Foo::bar and a member
+function named Foo::method that is defined somewhere. You still need to
+define @emph{both} method() and bar in some source file. According to
+the draft ANSI standard, you must supply an initializer, such as
+
+@example
+int Foo::bar = 0;
+@end example
+
+@noindent
+in one (and only one) source file.
+
+@node internal compiler error, bug reports, static data members, User Problems
+@section What does ``Internal compiler error'' mean?
+
+It means that the compiler has detected a bug in itself. Unfortunately,
+g++ still has many bugs, though it is a lot better than it used to be.
+If you see this message, please send in a complete bug report (see next
+section).
+
+@node bug reports, porting to g++, internal compiler error, User Problems
+@section I think I have found a bug in g++.
+
+@cindex Bug in g++, newly found
+``I think I have found a bug in g++, but I'm not sure. How do I know,
+and who should I tell?''
+
+@cindex Manual, for gcc
+First, see the excellent section on bugs and bug reports in the gcc manual
+(which is included in the gcc distribution). As a short summary of that
+section: if the compiler gets a fatal signal, for any input, it's a bug
+(newer versions of g++ will ask you to send in a bug report when they
+detect an error in themselves). Same thing for producing invalid
+assembly code.
+
+When you report a bug, make sure to describe your platform (the type of
+computer, and the version of the operating system it is running) and the
+version of the compiler that you are running. See the output of the
+command @code{g++ -v} if you aren't sure. Also provide enough code
+so that the g++ maintainers can duplicate your bug. Remember that the
+maintainers won't have your header files; one possibility is to send
+the output of the preprocessor (use @code{g++ -E} to get this). This
+is what a ``complete bug report'' means.
+
+I will add some extra notes that are C++-specific, since the notes from
+the gcc documentation are generally C-specific.
+
+@cindex g++ bug report
+First, mail your bug report to "bug-g++@@prep.ai.mit.edu". You may also
+post to @file{gnu.g++.bug}, but it's better to use mail, particularly if you
+have any doubt as to whether your news software generates correct reply
+addresses. Don't mail C++ bugs to bug-gcc@@prep.ai.mit.edu.
+
+@strong{News:} as I write this (late February 1996) the gateway
+connecting the bug-g++ mailing list and the @file{gnu.g++.bug} newsgroup
+is (temporarily?) broken. Please mail, do not post bug reports.
+
+@cindex libg++ bug report
+If your bug involves libg++ rather than the compiler, mail to
+bug-lib-g++@@prep.ai.mit.edu. If you're not sure, choose one, and if you
+guessed wrong, the maintainers will forward it to the other list.
+
+@cindex C++, reference books
+@cindex ARM [Annotated C++ Ref Manual]
+Second, if your program does one thing, and you think it should do
+something else, it is best to consult a good reference if in doubt.
+The standard reference is the draft working paper from the ANSI/ISO
+C++ standardization committee, which you can get on the net.
+For PostScript and PDF (Adobe Acrobat) versions, see the
+archive at @file{ftp://research.att.com/dist/stdc++/WP}. For HTML and ASCII
+versions, see @file{ftp://ftp.cygnus.com/pub/g++}. On the World Wide Web, see
+@file{http://www.cygnus.com/misc/wp/}.
+
+An older
+standard reference is "The Annotated C++ Reference Manual", by Ellis and
+Stroustrup (copyright 1990, ISBN #0-201-51459-1). This is what they're
+talking about on the net when they refer to ``the ARM''. But you should
+know that changes have been made to the language since then.
+
+The ANSI/ISO C++ standards committee have adopted some changes to the
+C++ language since the publication of the original ARM, and newer
+versions of g++ (2.5.x and later) support some of these changes, notably
+the mutable keyword (added in 2.5.0), the bool type (added in 2.6.0),
+and changes in the scope of variables defined in for statements (added
+in 2.7.0).
+You can obtain an addendum to the ARM explaining many of these changes by FTP
+from @file{ftp://ftp.std.com/AW/stroustrup2e/new_iso.ps}.
+
+@cindex AT&T cfront
+Note that the behavior of (any version of) AT&T's "cfront" compiler is
+NOT the standard for the language.
+
+@node porting to g++, name mangling, bug reports, User Problems
+@section Porting programs from other compilers to g++
+
+``I have a program that runs on <some other C++ compiler>, and I want
+to get it running under g++. Is there anything I should watch out
+for?''
+
+@cindex Porting to g++
+
+Note that g++ supports many of the newer keywords that have recently
+been added to the language. Your other C++ compiler may not support
+them, so you may need to rename variables and members that conflict
+with these keywords.
+
+There are two other reasons why a program that worked under one compiler
+might fail under another: your program may depend on the order of
+evaluation of side effects in an expression, or it may depend on the
+lifetime of a temporary (you may be assuming that a temporary object
+"lives" longer than the standard guarantees). As an example of the
+first:
+
+@example
+void func(int,int);
+
+int i = 3;
+func(i++,i++);
+@end example
+
+@cindex Order of evaluation, problems in porting
+Novice programmers think that the increments will be evaluated in strict
+left-to-right order. Neither C nor C++ guarantees this; the second
+increment might happen first, for example. func might get 3,4, or it
+might get 4,3.
+
+@cindex Classes, problems in porting
+@cindex Problems in porting, class
+The second problem often happens with classes like the libg++ String
+class. Let's say I have
+
+@example
+String func1();
+void func2(const char*);
+@end example
+
+and I say
+
+@example
+func2(func1());
+@end example
+
+because I know that class String has an "operator const char*". So what
+really happens is
+
+@example
+func2(func1().convert());
+@end example
+
+@cindex temporaries
+where I'm pretending I have a convert() method that is the same as the
+cast. This is unsafe in g++ versions before 2.6.0, because the
+temporary String object may be deleted after its last use (the call to
+the conversion function), leaving the pointer pointing to garbage, so by
+the time func2 is called, it gets an invalid argument.
+
+@cindex ANSI draft standard
+Both the cfront and the old g++ behaviors are legal according to the ARM,
+but the powers that be have decided that compiler writers were given
+too much freedom here.
+
+The ANSI C++ committee has now come to a resolution of the lifetime of
+temporaries problem: they specify that temporaries should be deleted at
+end-of-statement (and at a couple of other points). This means that g++
+versions before 2.6.0 now delete temporaries too early, and cfront
+deletes temporaries too late. As of version 2.6.0, g++ does things
+according to the new standard.
+
+@cindex Scope, problems in porting
+@cindex Problems in porting, scope
+For now, the safe way to write such code is to give the temporary a name,
+which forces it to live until the end of the scope of the name. For
+example:
+
+@example
+String& tmp = func1();
+func2(tmp);
+@end example
+
+Finally, like all compilers (but especially C++ compilers, it seems),
+g++ has bugs, and you may have tweaked one. If so, please file a bug
+report (after checking the above issues).
+
+@node name mangling, problems linking with other libraries, porting to g++, User Problems
+@section Why does g++ mangle names differently from other C++ compilers?
+
+See the answer to the next question.
+@cindex Mangling names
+
+@node problems linking with other libraries, documentation, name mangling, User Problems
+@section Why can't g++ code link with code from other C++ compilers?
+
+``Why can't I link g++-compiled programs against libraries compiled by
+some other C++ compiler?''
+
+@cindex Mangling names
+@cindex Cygnus Support
+Some people think that,
+if only the FSF and Cygnus Support folks would stop being
+stubborn and mangle names the same way that, say, cfront does, then any
+g++-compiled program would link successfully against any cfront-compiled
+library and vice versa. Name mangling is the least of the problems.
+Compilers differ as to how objects are laid out, how multiple inheritance
+is implemented, how virtual function calls are handled, and so on, so if
+the name mangling were made the same, your programs would link against
+libraries provided from other compilers but then crash when run. For this
+reason, the ARM @emph{encourages} compiler writers to make their name mangling
+different from that of other compilers for the same platform.
+Incompatible libraries are then detected at link time, rather than at run
+time.
+@cindex ARM [Annotated C++ Ref Manual]
+@cindex Compiler differences
+
+@node documentation, templates, problems linking with other libraries, User Problems
+@section What documentation exists for g++ 2.x?
+
+@cindex g++, documentation
+Relatively little.
+While the gcc manual that comes with the distribution has some coverage
+of the C++ part of the compiler, it focuses mainly on the C compiler
+(though the information on the ``back end'' pertains to C++ as well).
+Still, there is useful information on the command line options and the
+#pragma interface and #pragma implementation directives in the manual,
+and there is a useful section on template instantiation in the 2.6 version.
+There is a Unix-style manual entry, "g++.1", in the gcc-2.x
+distribution; the information here is a subset of what is in the manual.
+
+You can buy a nicely printed and bound copy of this manual from the FSF;
+see above for ordering information.
+
+A draft of a document describing the g++ internals appears in the gcc
+distribution (called g++int.texi); it is incomplete but gives lots of
+information.
+
+For class libraries, there are several resources available:
+
+@itemize @bullet
+@item
+The libg++ distribution has a manual
+@file{libg++/libg++.texi} describing the old libg++ classes, and
+another manual @file{libio/iostream.texi} describing the iostreams
+implementation.
+@item
+While there is no libg++-specific document describing the STL
+implementation, SGI's web site, at @file{http://www.sgi.com/Technology/STL/},
+is an excellent resource.
+@end itemize
+
+@node templates, undefined templates, documentation, User Problems
+@section Problems with the template implementation
+
+@cindex g++, template support
+@cindex Templates
+
+g++ does not implement a separate pass to instantiate template functions
+and classes at this point; for this reason, it will not work, for the most
+part, to declare your template functions in one file and define them in
+another. The compiler will need to see the entire definition of the
+function, and will generate a static copy of the function in each file
+in which it is used.
+
+(The experimental template repository code (@pxref{repository}) that
+can be added to 2.7.0 or later does implement a separate pass, but there
+is still no searching of files that the compiler never saw).
+
+@cindex -fno-implicit-templates
+For version 2.6.0, however, a new switch @code{-fno-implicit-templates}
+was added; with this switch, templates are expanded only under user
+control. I recommend that all g++ users that use templates read the
+section ``Template Instantiation'' in the gcc manual (version 2.6.x
+and newer). g++ now supports explicit template expansion using the
+syntax from the latest C++ working paper:
+
+@example
+template class A<int>;
+template ostream& operator << (ostream&, const A<int>&);
+@end example
+
+@cindex template limitations
+As of version 2.6.3, there are still a few limitations in the template
+implementation besides the above (thanks to Jason Merrill for this info):
+These are still present in version 2.7.2, but a new implementation of
+templates planned for version 2.8 will eliminate them.
+
+@enumerate 1
+@item
+Static data member templates are not supported. You can work around
+this by explicitly declaring the static variable for each template
+specialization:
+
+@example
+template <class T> struct A @{
+ static T t;
+@};
+
+template <class T> T A<T>::t = 0; // gets bogus error
+int A<int>::t = 0; // OK (workaround)
+@end example
+
+(still a limitation in 2.7.2)
+
+@item
+Template member names are not available when defining member function
+templates.
+
+@example
+template <class T> struct A @{
+ typedef T foo;
+ void f (foo);
+ void g (foo arg) @{ ... @}; // this works
+@};
+
+template <class T> void A<T>::f (foo) @{ @} // gets bogus error
+@end example
+
+@item
+Templates are instantiated using the parser. This results in two
+problems:
+
+a) Class templates are instantiated in some situations where such
+instantiation should not occur.
+
+@example
+template <class T> class A @{ @};
+A<int> *aip = 0; // should not instantiate A<int> (but does)
+@end example
+
+b) Function templates cannot be inlined at the site of their
+instantiation.
+
+@example
+template <class T> inline T min (T a, T b) @{ return a < b ? a : b; @}
+
+void f () @{
+ int i = min (1, 0); // not inlined
+@}
+
+void g () @{
+ int j = min (1, 0); // inlined
+@}
+@end example
+
+A workaround that works in version 2.6.1 and later is to specify
+
+@example
+extern template int min (int, int);
+@end example
+
+before @code{f()}; this will force it to be instantiated (though not
+emitted).
+
+@item
+Member function templates are always instantiated when their containing
+class is. This is wrong.
+@end enumerate
+
+@node undefined templates, redundant templates, templates, User Problems
+@section I get undefined symbols when using templates
+
+(Thanks to Jason Merrill for this section).
+
+@cindex template instantiation
+g++ does not automatically instantiate templates defined in other files.
+Because of this, code written for cfront will often produce undefined
+symbol errors when compiled with g++. You need to tell g++ which template
+instances you want, by explicitly instantiating them in the file where they
+are defined. For instance, given the files
+
+@file{templates.h}:
+@example
+template <class T>
+class A @{
+public:
+ void f ();
+ T t;
+@};
+
+template <class T> void g (T a);
+@end example
+
+@file{templates.cc}:
+@example
+#include "templates.h"
+
+template <class T>
+void A<T>::f () @{ @}
+
+template <class T>
+void g (T a) @{ @}
+@end example
+
+
+main.cc:
+@example
+#include "templates.h"
+
+main ()
+@{
+ A<int> a;
+ a.f ();
+ g (a);
+@}
+@end example
+
+compiling everything with @code{g++ main.cc templates.cc} will result in
+undefined symbol errors for @samp{A<int>::f ()} and @samp{g (A<int>)}. To
+fix these errors, add the lines
+
+@example
+template class A<int>;
+template void g (A<int>);
+@end example
+
+to the bottom of @samp{templates.cc} and recompile.
+
+@node redundant templates, Standard Template Library, undefined templates, User Problems
+@section I get multiply defined symbols using templates
+
+You may be running into a bug that was introduced in version 2.6.1
+(and is still present in 2.6.3) that generated external linkage
+for templates even when neither @code{-fexternal-templates} nor
+@code{-fno-implicit-templates} is specified. There is a patch for
+this problem at @*
+@file{ftp://ftp.cygnus.com/pub/g++/gcc-2.6.3-template-fix}.
+
+I recommend either applying the patch or
+using @code{-fno-implicit-templates}
+together with explicit template instantiation as described in previous
+sections.
+
+This bug is fixed in 2.7.0.
+
+@node Standard Template Library, STL and string, redundant templates, User Problems
+@section Does g++ support the Standard Template Library?
+
+@cindex STL
+@cindex Standard Template Library
+The Standard Template Library (STL) uses many of the extensions that the
+ANSI/ISO committee has made to templates, and g++ doesn't support
+some of these yet. So if you grab HP's free implementation of STL it
+isn't going to work. However, starting with libg++-2.6.2 libg++ contains a
+hacked version of STL, based on work by Carsten Bormann, which permits
+g++ to compile at least the containers (thanks to Per Bothner for this
+text).
+
+Actually, as of libg++ version 2.7.2 most of this works quite well, most
+of the time;
+I've succeeded
+in making significant use of it.
+Almost all of the ObjectSpace examples (a set of
+over 200 simple examples of STL usage) now work.
+
+When version 2.8.0 is out (with its complete redesign of the template
+implementation) a much more complete implementation of the
+STL (based on a newer free implementation from SGI) will be included.
+In the meantime, a group at the Moscow Center for Sparc Technology has
+a port of the SGI STL implementation that mostly works with gcc-2.7.2.
+See
+@file{http://www.ipmce.su/people/fbp/stl/stlport.html}.
+
+In addition, there are several commercial suppliers of STL implementations;
+ObjectSpace's version supports gcc-2.7.x.
+
+Mumit Khan has produced an ``STL newbie guide'' with lots of information
+on using STL with gcc. See
+
+@file{http://www.xraylith.wisc.edu/~khan/software/stl/STL.newbie.html}
+
+@node STL and string, exceptions, Standard Template Library, User Problems
+@section I'm having problems mixing STL and the standard string class
+
+This is due to a bug in g++ version 2.7.2 and 2.7.2.1; the compiler
+is confused by the operator declarations. There is an easy workaround,
+however; just make sure that the @code{<string>} header is included
+before any STL headers. That is, just say
+
+@example
+#include <string>
+@end example
+
+before any other @code{#include} directives.
+
+Unfortunately, this doesn't solve all problems; you may still have
+difficulty with the relational operators !=, <=, >, and >=, thanks
+to a conflict with the very general definition of these operators
+in function.h. One trick that sometimes works is to try to use ==
+and < in your code instead of the other operators. Another is to
+use a derived class of <string>. The only completely satisfactory
+solution, I'm afraid, is to wait for the new release.
+
+@node exceptions, namespaces, STL and string, User Problems
+@section Problems and limitations with exceptions
+
+Recent g++ versions provide limited support for exceptions. You must
+provide the @code{-fhandle-exceptions} flag to enable exception
+handling. As of version 2.7.2, exceptions may not work properly
+(and you may get odd error messages when compiling) if you turn
+on optimization (the @code{-O} flag).
+
+You must give the @code{-frtti} switch to enable catching
+of derived exception objects with handlers for the base exception class;
+if @code{-frtti} is not given, only exact type matching works.
+
+For exception handling to work with 2.7.0 your CPU must be a SPARC,
+RS6000/PowerPC, 386/486/Pentium, or ARM. Release 2.7.1 added support
+for the Alpha, and ``m68k is rumored to work on some platforms''
+and ``VAX may also work'' (according to Mike Stump).
+@emph{It still doesn't work on HP-PA or MIPS platforms.}
+
+@node namespaces, agreement with standards, exceptions, User Problems
+@section Does g++ support namespaces?
+
+As of version 2.7.2, g++ recognizes the keywords @code{namespace} and
+@code{using}, and there is some rudimentary code present, but almost
+nothing connected with namespaces works yet. It appears that this will
+still be true when 2.8.0 is released.
+
+@node agreement with standards, compiling standard libraries, namespaces, User Problems
+@section What are the differences between g++ and the ARM specification of C++?
+
+@cindex ARM [Annotated C++ Ref Manual]
+@cindex exceptions
+As of version 2.7.0, g++ has exception support on most but not all
+platforms
+(no support on MIPS-based platforms yet), but
+it doesn't work right if optimization is enabled, which means the
+exception
+implementation is still
+not really ready for production use.
+
+
+@cindex mutable
+Some features that the ANSI/ISO standardization committee has voted in
+that don't appear in the ARM are supported, notably the @code{mutable}
+keyword, in version 2.5.x. 2.6.x adds support for the built-in boolean
+type @code{bool}, with constants @code{true} and @code{false}. The
+beginnings of run-time type identification are present, so there are
+more reserved words: @code{typeid}, @code{static_cast},
+@code{reinterpret_cast}, @code{const_cast}, and @code{dynamic_cast}.
+
+@cindex g++ bugs
+As with any beta-test compiler, there are bugs. You can help improve
+the compiler by submitting detailed bug reports.
+
+One of the weakest areas of g++ other than templates is the resolution
+of overloaded functions and operators in complex cases. The usual
+symptom is that in a case where the ARM says that it is ambiguous which
+function should be chosen, g++ chooses one (often the first one
+declared). This is usually not a problem when porting C++ code from
+other compilers to g++, but shows up as errors when code developed under
+g++ is ported to other compilers. (I believe this is no longer a
+significant problem in 2.7.0).
+
+[A full bug list would be very long indeed, so I won't put one here.
+I may add a list of frequently-reported bugs and "non-bugs" like the
+static class members issue mentioned above].
+
+@node compiling standard libraries, debugging on SVR4 systems, agreement with standards, User Problems
+@section Will g++ compile InterViews? The NIH class library? Rogue Wave?
+
+@cindex NIH class library
+@cindex NIHCL with g++
+The NIH class library uses a non-portable, compiler-dependent hack
+to initialize itself, which makes life difficult for g++ users.
+It will not work without modification, and I don't know what modifications
+are required or whether anyone has done them successfully.
+
+In short, it's not going to happen any time soon (previous FAQs referred
+to patches that a new NIHCL release would hopefully contain, but this
+hasn't happened).
+
+@strong{Note:} I thought I saw an item indicating that someone
+@emph{had} patched NIHCL to work with g++. Any pointers?
+
+@cindex InterViews
+I think that as of version 2.5.6, the standard g++ will compile the
+standard 3.1 InterViews completely successfully.
+Note that you'll need the @code{-fno-for-scope} flag
+if you use gcc-2.7.0; with 2.7.2 you may be able to omit this flag
+but you'll get warnings.
+
+@cindex Rogue Wave
+According to Jason Merrill, gcc-2.7.0 and newer works with Rogue
+Wave's @code{tools.h++} class library, but you may want to grab
+@file{ftp://ftp.cygnus.com/pub/g++/Tools.h++-6.1-patch}. Again,
+you'll need the @code{-fno-for-scope} flag since Rogue Wave hasn't
+fixed their code to comply with the new standard yet.
+
+@node debugging on SVR4 systems, debugging problems on Solaris, compiling standard libraries, User Problems
+@section Debugging on SVR4 systems
+@cindex System VR4, debugging
+
+``How do I get debugging to work on my System V Release 4 system?''
+
+@cindex DWARF debug format
+
+Most systems based on System V Release 4 (except Solaris) encode symbolic
+debugging information in a format known as `DWARF'.
+
+Although the GNU C compiler already knows how to write out symbolic debugging
+information in the DWARF format, the GNU C++ compiler does not yet have this
+feature yet. However, work is in progress for DWARF 2 debug support for
+gcc and g++ and will be available in a future release (probably 2.8.0).
+
+@cindex stabs
+@cindex --with-stabs
+
+In the meantime, you @emph{can} get g++ debugging under SVR4 systems by
+configuring gcc with the @code{--with-stabs} option. This causes gcc to
+use an alternate debugging format, one more like that used under SunOS4.
+You won't need to do anything special to GDB; it will always understand
+the ``stabs'' format.
+
+@node debugging problems on Solaris, X11 conflicts with libg++, debugging on SVR4 systems, User Problems
+@section debugging problems on Solaris
+
+``I'm on Solaris, and gdb says it doesn't know about some of my local
+symbols. Help!''
+
+This problem was introduced in gcc 2.7.2; debug symbols for
+locals that aren't declared at the beginning of a block come out in the
+wrong order, and gdb can't find such symbols.
+
+This problem is fixed in gcc-2.7.2.1.
+
+@node X11 conflicts with libg++, assignment to streams, debugging problems on Solaris, User Problems
+@section X11 conflicts with libg++ in definition of String
+@cindex String, conflicts in definition
+
+``X11 and Motif define String, and this conflicts with the String class
+in libg++. How can I use both together?''
+
+One possible method is the following:
+
+@example
+#define String XString
+#include <X11/Intrinsic.h>
+/* include other X11 and Motif headers */
+#undef String
+@end example
+
+and remember to use the correct @code{String} or @code{XString} when
+you declare things later.
+
+@node assignment to streams, , X11 conflicts with libg++, User Problems
+@section Why can't I assign one stream to another?
+
+[ Thanks to Per Bothner and Jerry Schwarz for this section. ]
+
+Assigning one stream to another seems like a reasonable thing to do, but
+it's a bad idea. Usually, this comes up because people want to assign
+to @code{cout}. This is poor style, especially for libraries, and is
+contrary to good object-oriented design. (Libraries that write directly
+to @code{cout} are less flexible, modular, and object-oriented).
+
+The iostream classes do not allow assigning to arbitrary streams, because
+this can violate typing:
+
+@example
+ifstream foo ("foo");
+istrstream str(...);
+foo = str;
+foo->close (); /* Oops! Not defined for istrstream! */
+@end example
+
+@cindex assignment to cout
+
+The original cfront implementation of iostreams by Jerry Schwarz allows
+you to assign to @code{cin}, @code{cout}, @code{cerr}, and @code{clog},
+but this is not part of the draft standard for iostreams and generally
+isn't considered a good idea, so standard-conforming code shouldn't use
+this technique.
+
+The GNU implementation of iostream did not support assigning to
+@code{cin}, @code{cout}, @code{cerr}, and @code{clog}
+for quite a while, but it now does, for backward
+compatibility with cfront iostream (versions 2.6.1 and later of libg++).
+
+The ANSI/ISO C++ Working Paper does provide ways of changing the
+streambuf associated with a stream. Assignment isn't allowed;
+there is an explicit named member that must be used.
+
+However, it is not wise to do this, and the results are confusing. For
+example: @code{fstream::rdbuf} is supposed to return the @emph{original}
+filebuf, not the one you assigned. (This is not yet implemented in GNU
+iostream.) This must be so because @code{fstream::rdbuf} is defined to
+return a @code{filebuf *}.
+
+@node legalities, index, User Problems, Top
+@chapter What are the rules for shipping code built with g++ and libg++?
+@cindex Shipping rules
+@cindex GPL [GNU Public License]
+
+``Is it is possible to distribute programs for profit that are created
+with g++ and use the g++ libraries?''
+
+I am not a lawyer, and this is not legal advice. In any case, I have
+little interest in telling people how to violate the spirit of the
+GNU licenses without violating the letter. This section tells you
+how to comply with the intention of the GNU licenses as best I understand
+them.
+
+@cindex FSF [Free Software Foundation]
+The FSF has no objection to your making money. Its only interest is that
+source code to their programs, and libraries, and to modified versions of
+their programs and libraries, is always available.
+
+The short answer is that you do not need to release the source to
+your program, but you can't just ship a stripped executable either,
+unless you use only the subset of libg++ that includes the iostreams
+classes (see discussion below) or the new libstdc++ library (available
+in libg++ 2.6.2 and later).
+
+Compiling your code with a GNU compiler does not affect its copyright;
+it is still yours. However, in order to ship code that links in a GNU
+library such as libg++ there are certain rules you must follow. The
+rules are described in the file COPYING.LIB that accompanies gcc
+distributions; it is also included in the libg++ distribution.
+See that file for the exact rules. The agreement is called the
+Library GNU Public License or LGPL. It is much "looser" than the
+GNU Public License, or GPL, that covers must GNU programs.
+
+@cindex libg++, shipping code
+Here's the deal: let's say that you use some version of libg++,
+completely unchanged, in your software, and you want to ship only
+a binary form of your code. You can do this, but there are several
+special requirements. If you want to use libg++ but ship only object
+code for your code, you have to ship source for libg++ (or ensure
+somehow that your customer already has the source for the exact
+version you are using), and ship your application in linkable form.
+You cannot forbid your customer from reverse-engineering or extending
+your program by exploiting its linkable form.
+
+@cindex libg++, modifying
+Furthermore, if you modify libg++ itself, you must provide source
+for your modifications (making a derived class does not count as
+modifying the library -- that is "a work that uses the library").
+
+@cindex special copying conditions for iostreams
+For certain portions of libg++ that implement required parts of the C++
+language (such as iostreams and other standard classes), the FSF has
+loosened the copyright requirement still more by adding the ``special
+exception'' clause, which reads as follows:
+
+@quotation
+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.
+@end quotation
+
+If your only use of libg++ uses code with this exception, you may ship
+stripped executables or license your executables under different
+conditions without fear of violating an FSF copyright. It is the intent
+of FSF and Cygnus that, as the other classes required by the ANSI/ISO
+draft standard are developed, these will also be placed under this
+``special exception'' license.
+The code in the new libstdc++ library, intended to implement standard
+classes as defined by ANSI/ISO, is also licensed this way.
+
+To avoid coming under the influence of the LGPL, you can link with
+@file{-liostream} rather than @file{-lg++} (for version 2.6.x and
+earlier), or @file{-lstdc++} now that it is available. In version 2.7.0
+all the standard classes are in @file{-lstdc++}; you can do the link
+step with @code{c++} instead of @code{g++} to search only the
+@file{-lstdc++} library and avoid the LGPL'ed code in @file{-lg++}.
+
+If you wish to discuss legal issues connected with GNU software on the
+net, please use @file{gnu.misc.discuss}, not the technical newsgroups.
+
+@node index, , legalities, Top
+@comment node-name, next, previous, up
+@appendix Concept Index
+
+@printindex cp
+
+@page
+@contents
+@bye
diff --git a/gnu/usr.bin/gcc/cp/g++spec.c b/gnu/usr.bin/gcc/cp/g++spec.c
new file mode 100644
index 00000000000..66b27565766
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/g++spec.c
@@ -0,0 +1,255 @@
+/* Specific flags and argument handling of the C++ front-end.
+ Copyright (C) 1996, 1997 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.h"
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#include "gansidecl.h"
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+/* This bit is set if we saw a `-xfoo' language specification. */
+#define LANGSPEC (1<<1)
+/* This bit is set if they did `-lm' or `-lmath'. */
+#define MATHLIB (1<<2)
+/* This bit is set if they did `-lc'. */
+#define WITHLIBC (1<<3)
+
+#ifndef MATH_LIBRARY
+#define MATH_LIBRARY "-lm"
+#endif
+
+extern char *xmalloc PROTO((size_t));
+
+void
+lang_specific_driver (fn, in_argc, in_argv)
+ void (*fn)();
+ int *in_argc;
+ char ***in_argv;
+{
+ int i, j;
+
+ /* If non-zero, the user gave us the `-v' flag. */
+ int saw_verbose_flag = 0;
+
+ /* This will be 0 if we encounter a situation where we should not
+ link in libstdc++. */
+ int library = 1;
+
+ /* The number of arguments being added to what's in argv, other than
+ libraries. We use this to track the number of times we've inserted
+ -xc++/-xnone. */
+ int added = 2;
+
+ /* Used to track options that take arguments, so we don't go wrapping
+ those with -xc++/-xnone. */
+ char *quote = NULL;
+
+ /* The new argument list will be contained in this. */
+ char **arglist;
+
+ /* Non-zero if we saw a `-xfoo' language specification on the
+ command line. Used to avoid adding our own -xc++ if the user
+ already gave a language for the file. */
+ int saw_speclang = 0;
+
+ /* "-lm" or "-lmath" if it appears on the command line. */
+ char *saw_math = 0;
+
+ /* "-lc" if it appears on the command line. */
+ char *saw_libc = 0;
+
+ /* An array used to flag each argument that needs a bit set for
+ LANGSPEC, MATHLIB, or WITHLIBC. */
+ int *args;
+
+ /* By default, we throw on the math library. */
+ int need_math = 1;
+
+ /* The total number of arguments with the new stuff. */
+ int argc;
+
+ /* The argument list. */
+ char **argv;
+
+ /* The total number of arguments with the new stuff. */
+ int num_args = 1;
+
+ argc = *in_argc;
+ argv = *in_argv;
+
+
+ args = (int *) xmalloc (argc * sizeof (int));
+ bzero ((char *) args, argc * sizeof (int));
+
+ for (i = 1; i < argc; i++)
+ {
+ /* If the previous option took an argument, we swallow it here. */
+ if (quote)
+ {
+ quote = NULL;
+ continue;
+ }
+
+ /* We don't do this anymore, since we don't get them with minus
+ signs on them. */
+ if (argv[i][0] == '\0' || argv[i][1] == '\0')
+ continue;
+
+ if (argv[i][0] == '-')
+ {
+ if (library != 0 && (strcmp (argv[i], "-nostdlib") == 0
+ || strcmp (argv[i], "-nodefaultlibs") == 0))
+ {
+ library = 0;
+ }
+ else if (strcmp (argv[i], "-lm") == 0
+ || strcmp (argv[i], "-lmath") == 0
+#ifdef ALT_LIBM
+ || strcmp (argv[i], ALT_LIBM) == 0
+#endif
+ )
+ {
+ args[i] |= MATHLIB;
+ need_math = 0;
+ }
+ else if (strcmp (argv[i], "-lc") == 0)
+ args[i] |= WITHLIBC;
+ else if (strcmp (argv[i], "-v") == 0)
+ {
+ saw_verbose_flag = 1;
+ if (argc == 2)
+ {
+ /* If they only gave us `-v', don't try to link
+ in libg++. */
+ library = 0;
+ }
+ }
+ else if (strncmp (argv[i], "-x", 2) == 0)
+ saw_speclang = 1;
+ else if (((argv[i][2] == '\0'
+ && (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
+ || strcmp (argv[i], "-Tdata") == 0))
+ quote = argv[i];
+ else if (library != 0 && ((argv[i][2] == '\0'
+ && (char *) strchr ("cSEM", argv[i][1]) != NULL)
+ || strcmp (argv[i], "-MM") == 0))
+ {
+ /* Don't specify libraries if we won't link, since that would
+ cause a warning. */
+ library = 0;
+ added -= 2;
+ }
+ else
+ /* Pass other options through. */
+ continue;
+ }
+ else
+ {
+ int len;
+
+ if (saw_speclang)
+ {
+ saw_speclang = 0;
+ continue;
+ }
+
+ /* If the filename ends in .c or .i, put options around it.
+ But not if a specified -x option is currently active. */
+ len = strlen (argv[i]);
+ if (len > 2
+ && (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i')
+ && argv[i][len - 2] == '.')
+ {
+ args[i] |= LANGSPEC;
+ added += 2;
+ }
+ }
+ }
+
+ if (quote)
+ (*fn) ("argument to `%s' missing\n", quote);
+
+ /* If we know we don't have to do anything, bail now. */
+ if (! added && ! library)
+ {
+ free (args);
+ return;
+ }
+
+ num_args = argc + added + need_math;
+ arglist = (char **) xmalloc (num_args * sizeof (char *));
+
+ /* NOTE: We start at 1 now, not 0. */
+ for (i = 0, j = 0; i < argc; i++, j++)
+ {
+ arglist[j] = argv[i];
+
+ /* Make sure -lstdc++ is before the math library, since libstdc++
+ itself uses those math routines. */
+ if (!saw_math && (args[i] & MATHLIB) && library)
+ {
+ --j;
+ saw_math = argv[i];
+ }
+
+ if (!saw_libc && (args[i] & WITHLIBC) && library)
+ {
+ --j;
+ saw_libc = argv[i];
+ }
+
+ /* Wrap foo.c and foo.i files in a language specification to
+ force the gcc compiler driver to run cc1plus on them. */
+ if (args[i] & LANGSPEC)
+ {
+ int len = strlen (argv[i]);
+ if (argv[i][len - 1] == 'i')
+ arglist[j++] = "-xc++-cpp-output";
+ else
+ arglist[j++] = "-xc++";
+ arglist[j++] = argv[i];
+ arglist[j] = "-xnone";
+ }
+ }
+
+ /* Add `-lstdc++' if we haven't already done so. */
+ if (library)
+ arglist[j++] = "-lstdc++";
+ if (saw_math)
+ arglist[j++] = saw_math;
+ else if (library)
+ arglist[j++] = MATH_LIBRARY;
+ if (saw_libc)
+ arglist[j++] = saw_libc;
+
+ arglist[j] = NULL;
+
+ *in_argc = j;
+ *in_argv = arglist;
+}
diff --git a/gnu/usr.bin/gcc/cp/inc/exception b/gnu/usr.bin/gcc/cp/inc/exception
new file mode 100644
index 00000000000..d38806b81c4
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/inc/exception
@@ -0,0 +1,42 @@
+// Exception Handling support header for -*- C++ -*-
+// Copyright (C) 1995, 1996 Free Software Foundation
+
+#ifndef __EXCEPTION__
+#define __EXCEPTION__
+
+#pragma interface "exception"
+
+extern "C++" {
+
+#if 0
+namespace std {
+#endif
+
+class exception {
+public:
+ exception () { }
+ virtual ~exception () { }
+ virtual const char* what () const;
+};
+
+class bad_exception : public exception {
+public:
+ bad_exception () { }
+ virtual ~bad_exception () { }
+};
+
+typedef void (*terminate_handler) ();
+typedef void (*unexpected_handler) ();
+
+terminate_handler set_terminate (terminate_handler);
+void terminate (void);
+unexpected_handler set_unexpected (unexpected_handler);
+void unexpected (void);
+bool uncaught_exception ();
+} // extern "C++"
+
+#if 0
+} // namespace std
+#endif
+
+#endif
diff --git a/gnu/usr.bin/gcc/cp/inc/new b/gnu/usr.bin/gcc/cp/inc/new
new file mode 100644
index 00000000000..f4b0b975cdb
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/inc/new
@@ -0,0 +1,48 @@
+// The -*- C++ -*- dynamic memory management header.
+// Copyright (C) 1994, 1996 Free Software Foundation
+
+#ifndef __NEW__
+#define __NEW__
+
+#pragma interface "new"
+#include <stddef.h>
+#include <exception>
+
+extern "C++" {
+
+#if 0
+namespace std {
+#endif
+
+ class bad_alloc : public exception {
+ public:
+ virtual const char* what() const throw() { return "bad_alloc"; }
+ };
+
+ struct nothrow_t {};
+ extern const nothrow_t nothrow;
+ typedef void (*new_handler)();
+ extern "C" new_handler set_new_handler (new_handler);
+
+#if 0
+} // namespace std
+#endif
+
+// G++ implementation internals
+extern new_handler __new_handler;
+extern "C" void __default_new_handler (void);
+
+// replaceable signatures
+void *operator new (size_t);
+void *operator new (size_t, const nothrow_t&) throw();
+void *operator new[] (size_t);
+void *operator new[] (size_t, const nothrow_t&) throw();
+void operator delete (void *) throw();
+void operator delete[] (void *) throw();
+
+// default placement versions of operator new
+inline void *operator new(size_t, void *place) throw() { return place; }
+inline void *operator new[](size_t, void *place) throw() { return place; }
+} // extern "C++"
+
+#endif
diff --git a/gnu/usr.bin/gcc/cp/inc/new.h b/gnu/usr.bin/gcc/cp/inc/new.h
new file mode 100644
index 00000000000..eed0910b668
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/inc/new.h
@@ -0,0 +1,13 @@
+// -*- C++ -*- forwarding header.
+
+#ifndef __NEW_H__
+#define __NEW_H__
+
+#include <new>
+
+#if 0
+using std::new_handler;
+using std::set_new_handler;
+#endif
+
+#endif // __NEW_H__
diff --git a/gnu/usr.bin/gcc/cp/inc/typeinfo b/gnu/usr.bin/gcc/cp/inc/typeinfo
new file mode 100644
index 00000000000..26526594db5
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/inc/typeinfo
@@ -0,0 +1,71 @@
+// RTTI support for -*- C++ -*-
+// Copyright (C) 1994, 1995, 1996 Free Software Foundation
+
+#ifndef __TYPEINFO__
+#define __TYPEINFO__
+
+#include <exception>
+
+extern "C++" {
+
+#if 0
+namespace std {
+#endif
+
+class type_info {
+private:
+ // assigning type_info is not supported. made private.
+ type_info& operator= (const type_info&);
+ type_info (const type_info&);
+
+protected:
+ type_info (const char *n): _name (n) { }
+
+ const char *_name;
+
+public:
+ // destructor
+ virtual ~type_info ();
+
+ bool before (const type_info& arg) const;
+ const char* name () const
+ { return _name; }
+ bool operator== (const type_info& arg) const;
+ bool operator!= (const type_info& arg) const;
+};
+
+// We can't rely on common symbols being shared between translation units
+// under Windows. Sigh.
+
+#ifndef _WIN32
+inline bool type_info::
+operator== (const type_info& arg) const
+{
+ return &arg == this;
+}
+
+inline bool type_info::
+operator!= (const type_info& arg) const
+{
+ return &arg != this;
+}
+#endif
+
+class bad_cast : public exception {
+public:
+ bad_cast() { }
+ virtual ~bad_cast() { }
+};
+
+class bad_typeid : public exception {
+ public:
+ bad_typeid () { }
+ virtual ~bad_typeid () { }
+};
+
+#if 0
+} // namespace std
+#endif
+
+} // extern "C++"
+#endif
diff --git a/gnu/usr.bin/gcc/cp/mpw-config.in b/gnu/usr.bin/gcc/cp/mpw-config.in
new file mode 100644
index 00000000000..88dd85f72e9
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/mpw-config.in
@@ -0,0 +1,11 @@
+# Configuration fragment for G++.
+# Most of the real configuration work happens in the main GCC configure.
+
+# We need to join some lines in the Makefile.in before the sed
+# process will work properly. The funky little sed script works by
+# recognizing lines with a trailing '$@ \', adding the next line to
+# its "pattern space", editing out the backslash and line, then
+# putting the result out.
+
+sed -e '/$@ \\/{N;s/$@ \\./$@ /;P;D;}' \Option-d
+ "{srcdir}"Makefile.in >"{o}"hacked_Makefile.in
diff --git a/gnu/usr.bin/gcc/cp/mpw-make.sed b/gnu/usr.bin/gcc/cp/mpw-make.sed
new file mode 100644
index 00000000000..120b5a1fa3a
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/mpw-make.sed
@@ -0,0 +1,112 @@
+# Sed commands to finish translating the G++ Unix makefile into MPW syntax.
+
+# Remove control-Ls, they upset MPW make.
+s/ //g
+
+# Remove references to always-empty variables used to mark things.
+/CYGNUS-LOCAL-/s/{CYGNUS-LOCAL-[a-z0-9]*}//g
+
+# Add a bunch of definitions, mostly empty.
+/^# Variables that exist for you to override.$/a\
+\
+xmake_file = \
+tmake_file = \
+build_xm_file = \
+MALLOC = \
+MD_DEPS = \
+REAL_H = \
+HOST_CC_LD = {CC_LD}\
+ALL_CCLDFLAGS = \
+HOST_CCLDFLAGS = \
+CONFIG_H = \
+LIBDEPS = \
+
+# The "target" variable is special to MPW make, avoid it.
+/{target}/s/{target}/{target_canonical}/g
+
+# Suppress the suppression of smart makes.
+/^\.y\.c/d
+
+# Whack out "..." assignments.
+/\.\.\./s/^\([a-z_]*= \.\.\.\)/#\1/
+
+# Previous edits go a little overboard, undo.
+/^objext = /s/"{o}"//
+
+# Always link in low-level MPW functions.
+/^LIBDEPS=/s/$/ ::strerror.c.o ::mpwlib.c.o/
+/{CLIB}/s/{CLIB}/ ::strerror.c.o ::mpwlib.c.o {CLIB}/
+
+# Don't get tricky about finding various .o file, point at dir above.
+/^SUBDIR_OBSTACK/s/`.*`/::obstack.c.o/
+/^SUBDIR_USE_ALLOCA/s/`.*`/::alloca.c.o/
+/^SUBDIR_MALLOC/s/`.*`//
+
+# Point includes at parent directly correctly.
+/^INCLUDES = /s/:\./::/g
+/^INCLUDES = /s/"{srcdir}"\.\./"{topsrcdir}"gcc:/g
+/^INCLUDES = /s,"{srcdir}"/\.\.,"{topsrcdir}"gcc:,g
+/^INCLUDES = /s,"{srcdir}":config,"{topsrcdir}"gcc:config:,g
+
+# Add the special MPW include dirs.
+/^INCLUDES = /s/$/ -i "{topsrcdir}"include:mpw: -i :::extra-include:/
+
+# A nasty hack to reduce confusion.
+/true/s/ ; @true$//
+
+# (should be in common translation?)
+/{CC_LD} /s/$/ {EXTRALIBS}/
+
+# Don't use general compiler flags (which may include definitions
+# and other compiler-only bits) with linking commands.
+/{CC_LD} /s/ALL_CFLAGS/ALL_CCLDFLAGS/
+
+# Whack out build rules that are not useful.
+/^Makefile \\Option-f /,/^$/d
+/^config.status \\Option-f /,/^$/d
+# (Note that MPW make is not case sensitive, and so this name
+# is considered the same as "md_file".)
+/^{MD_FILE} \\Option-f/,/^$/d
+
+# Depending on config.status is not useful for us.
+/config.status/s/ config.status//
+
+# Repeat of stuff from generic edit.
+/{s}/s/"{s}""{s}"/"{s}"/g
+/{s}/s/"{s}""{srcdir}"/"{s}"/g
+/{s}/s/"{srcdir}""{s}"/"{s}"/g
+
+# Fix references to C frontend files in main dir.
+/::c-/s/"{o}"::c-/"{o}":c-/g
+
+# Fix pathnames to generated files in the objdir.
+/parse/s/"{s}"parse\.\([chy]\)/"{o}"parse.\1/g
+/parse/s/^parse\.\([chy]\)/"{o}"parse.\1/
+/y.tab.c/s/"{s}"y\.tab\.c/"{o}"y.tab.c/g
+/y.tab.c/s/^y\.tab\.c/"{o}"y.tab.c/
+/y.tab.h/s/"{s}"y\.tab\.h/"{o}"y.tab.h/g
+/y.tab.h/s/^y\.tab\.h/"{o}"y.tab.h/
+
+# Put in the definition of YYEMPTY directly.
+/grep/s/grep .* >>/Echo '#define YYEMPTY -1' >>/
+
+# If the dates are wrong, then this tries to run gperf, which we don't
+# really want.
+/^"{srcdir}"hash.h/,/hash.h$/d
+
+# Sed the object file list instead of using cat (meow).
+/cat/s/`cat /`sed -e 's,:,::,g' -e 's,{objext},.o,g' /
+
+# Simplify dependencies of generated parser files.
+/^{PARSE_C}/s/^/#/
+/^stamp-parse/s/^stamp-parse/{PARSE_C}/
+
+# Fix the compile line for the generated parser.
+/{CC} -c/,/echo {PARSE_C}/c\
+ {CC} @DASH_C_FLAG@ {ALL_CFLAGS} {ALL_CPPFLAGS} {INCLUDES} {BIG_SWITCHFLAG} "{o}"parse.c -o "{o}"parse.c.o\
+
+# Change all Rez commands to use mac-gcc.r.
+/{REZ}/s/"{s}"[-a-zA-Z{}]*\.r/"{topsrcdir}"gcc:mac-gcc.r/
+
+# Remove pathname junk from the container name.
+/{REZ}/s/'"'::cc1plus'"'/'"'cc1plus'"'/
diff --git a/gnu/usr.bin/gcc/cp/new.cc b/gnu/usr.bin/gcc/cp/new.cc
new file mode 100644
index 00000000000..0db3497f1fa
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/new.cc
@@ -0,0 +1,31 @@
+// Implementation file for the -*- C++ -*- dynamic memory management header.
+// Copyright (C) 1996 Free Software Foundation
+
+// 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.
+
+// As a special exception, if you link this library with other files,
+// some of which are compiled with GCC, to produce an executable,
+// this library does not by itself 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.
+
+#pragma implementation "new"
+#include "new"
+
+const nothrow_t nothrow = { };
diff --git a/gnu/usr.bin/gcc/cp/new1.cc b/gnu/usr.bin/gcc/cp/new1.cc
new file mode 100644
index 00000000000..0ee111d2939
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/new1.cc
@@ -0,0 +1,54 @@
+// Support routine for the -*- C++ -*- dynamic memory management.
+// Copyright (C) 1997 Free Software Foundation
+
+// 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.
+
+// As a special exception, if you link this library with other files,
+// some of which are compiled with GCC, to produce an executable,
+// this library does not by itself 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.
+
+#include "new"
+
+extern "C" void *malloc (size_t);
+
+typedef void (*vfp)(void);
+extern vfp __new_handler;
+extern void __default_new_handler (void);
+
+void *operator new (size_t sz, const nothrow_t&) throw()
+{
+ void *p;
+ vfp handler = __new_handler;
+
+ /* malloc (0) is unpredictable; avoid it. */
+ if (sz == 0)
+ sz = 1;
+ p = (void *) malloc (sz);
+ while (p == 0)
+ {
+ if (! handler)
+ return 0;
+ (*handler) ();
+ p = (void *) malloc (sz);
+ }
+
+ return p;
+}
diff --git a/gnu/usr.bin/gcc/cp/new2.cc b/gnu/usr.bin/gcc/cp/new2.cc
new file mode 100644
index 00000000000..5aca49d21d1
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/new2.cc
@@ -0,0 +1,33 @@
+// Support routine for the -*- C++ -*- dynamic memory management.
+// Copyright (C) 1997 Free Software Foundation
+
+// 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.
+
+// As a special exception, if you link this library with other files,
+// some of which are compiled with GCC, to produce an executable,
+// this library does not by itself 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.
+
+#include "new"
+
+void *operator new[] (size_t sz, const nothrow_t& nothrow) throw()
+{
+ return ::operator new(sz, nothrow);
+}
diff --git a/gnu/usr.bin/gcc/cp/rtti.c b/gnu/usr.bin/gcc/cp/rtti.c
new file mode 100644
index 00000000000..e7b83d37726
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/rtti.c
@@ -0,0 +1,1394 @@
+/* RunTime Type Identification
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Mostly written by Jason Merrill (jason@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 "config.h"
+#include <stdio.h>
+#include "tree.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "output.h"
+#include "assert.h"
+
+#ifndef INT_TYPE_SIZE
+#define INT_TYPE_SIZE BITS_PER_WORD
+#endif
+
+extern struct obstack permanent_obstack;
+
+static tree call_void_fn PROTO((char *));
+static tree build_headof_sub PROTO((tree));
+static tree build_headof PROTO((tree));
+static tree get_tinfo_var PROTO((tree));
+static tree get_typeid_1 PROTO((tree));
+static tree ifnonnull PROTO((tree, tree));
+static tree build_dynamic_cast_1 PROTO((tree, tree));
+static void expand_si_desc PROTO((tree, tree));
+static void expand_class_desc PROTO((tree, tree));
+static void expand_attr_desc PROTO((tree, tree));
+static void expand_ptr_desc PROTO((tree, tree));
+static void expand_generic_desc PROTO((tree, tree, char *));
+static tree throw_bad_cast PROTO((void));
+static tree throw_bad_typeid PROTO((void));
+
+tree type_info_type_node;
+tree tinfo_fn_id;
+tree tinfo_fn_type;
+
+void
+init_rtti_processing ()
+{
+ type_info_type_node = xref_tag
+ (class_type_node, get_identifier ("type_info"), NULL_TREE, 1);
+ tinfo_fn_id = get_identifier ("__tf");
+ tinfo_fn_type = build_function_type
+ (build_reference_type (build_type_variant (type_info_type_node, 1, 0)),
+ void_list_node);
+}
+
+/* Given a pointer to an object with at least one virtual table
+ pointer somewhere, return a pointer to a possible sub-object that
+ has a virtual table pointer in it that is the vtable parent for
+ that sub-object. */
+
+static tree
+build_headof_sub (exp)
+ tree exp;
+{
+ tree type = TREE_TYPE (TREE_TYPE (exp));
+ tree basetype = CLASSTYPE_RTTI (type);
+ tree binfo = get_binfo (basetype, type, 0);
+
+ exp = convert_pointer_to_real (binfo, exp);
+ return exp;
+}
+
+/* Given the expression EXP of type `class *', return the head of the
+ object pointed to by EXP with type cv void*, if the class has any
+ virtual functions (TYPE_VIRTUAL_P), else just return the
+ expression. */
+
+static tree
+build_headof (exp)
+ tree exp;
+{
+ tree type = TREE_TYPE (exp);
+ tree aref;
+ tree offset;
+
+ if (TREE_CODE (type) != POINTER_TYPE)
+ {
+ error ("`headof' applied to non-pointer type");
+ return error_mark_node;
+ }
+ type = TREE_TYPE (type);
+
+ if (!TYPE_VIRTUAL_P (type))
+ return exp;
+
+ /* If we don't have rtti stuff, get to a sub-object that does. */
+ if (!CLASSTYPE_VFIELDS (TREE_TYPE (TREE_TYPE (exp))))
+ exp = build_headof_sub (exp);
+
+ /* We use this a couple of times below, protect it. */
+ exp = save_expr (exp);
+
+ aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), integer_zero_node);
+
+ if (flag_vtable_thunks)
+ offset = aref;
+ else
+ offset = build_component_ref (aref, delta_identifier, NULL_TREE, 0);
+
+ type = build_type_variant (ptr_type_node, TREE_READONLY (exp),
+ TREE_THIS_VOLATILE (exp));
+ return build (PLUS_EXPR, type, exp,
+ cp_convert (ptrdiff_type_node, offset));
+}
+
+/* Build a call to a generic entry point taking and returning void. */
+
+static tree
+call_void_fn (name)
+ char *name;
+{
+ tree d = get_identifier (name);
+ tree type;
+
+ if (IDENTIFIER_GLOBAL_VALUE (d))
+ d = IDENTIFIER_GLOBAL_VALUE (d);
+ else
+ {
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+
+ type = build_function_type (void_type_node, void_list_node);
+ d = build_lang_decl (FUNCTION_DECL, d, type);
+ DECL_EXTERNAL (d) = 1;
+ TREE_PUBLIC (d) = 1;
+ DECL_ARTIFICIAL (d) = 1;
+ pushdecl_top_level (d);
+ make_function_rtl (d);
+ assemble_external (d);
+
+ pop_obstacks ();
+ }
+
+ return build_call (d, void_type_node, NULL_TREE);
+}
+
+/* Get a bad_cast node for the program to throw...
+
+ See libstdc++/exception.cc for __throw_bad_cast */
+
+static tree
+throw_bad_cast ()
+{
+ return call_void_fn ("__throw_bad_cast");
+}
+
+static tree
+throw_bad_typeid ()
+{
+ return call_void_fn ("__throw_bad_typeid");
+}
+
+/* Return the type_info function associated with the expression EXP. If
+ EXP is a reference to a polymorphic class, return the dynamic type;
+ otherwise return the static type of the expression. */
+
+tree
+get_tinfo_fn_dynamic (exp)
+ tree exp;
+{
+ tree type;
+
+ if (exp == error_mark_node)
+ return error_mark_node;
+
+ if (type_unknown_p (exp))
+ {
+ error ("typeid of overloaded function");
+ return error_mark_node;
+ }
+
+ type = TREE_TYPE (exp);
+
+ /* peel back references, so they match. */
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ type = TREE_TYPE (type);
+
+ /* Peel off cv qualifiers. */
+ type = TYPE_MAIN_VARIANT (type);
+
+ /* If exp is a reference to polymorphic type, get the real type_info. */
+ if (TYPE_VIRTUAL_P (type) && ! resolves_to_fixed_type_p (exp, 0))
+ {
+ /* build reference to type_info from vtable. */
+ tree t;
+
+ if (! flag_rtti)
+ warning ("taking dynamic typeid of object without -frtti");
+
+ /* If we don't have rtti stuff, get to a sub-object that does. */
+ if (! CLASSTYPE_VFIELDS (type))
+ {
+ exp = build_unary_op (ADDR_EXPR, exp, 0);
+ exp = build_headof_sub (exp);
+ exp = build_indirect_ref (exp, NULL_PTR);
+ }
+
+ if (flag_vtable_thunks)
+ t = build_vfn_ref ((tree *) 0, exp, integer_one_node);
+ else
+ t = build_vfn_ref ((tree *) 0, exp, integer_zero_node);
+ TREE_TYPE (t) = build_pointer_type (tinfo_fn_type);
+ return t;
+ }
+
+ /* otherwise return the type_info for the static type of the expr. */
+ return get_tinfo_fn (TYPE_MAIN_VARIANT (type));
+}
+
+tree
+build_typeid (exp)
+ tree exp;
+{
+ exp = get_tinfo_fn_dynamic (exp);
+ exp = build_call (exp, TREE_TYPE (tinfo_fn_type), NULL_TREE);
+ return convert_from_reference (exp);
+}
+
+tree
+build_x_typeid (exp)
+ tree exp;
+{
+ tree cond = NULL_TREE;
+ tree type = TREE_TYPE (tinfo_fn_type);
+ int nonnull;
+
+ if (processing_template_decl)
+ return build_min_nt (TYPEID_EXPR, exp);
+
+ if (TREE_CODE (exp) == INDIRECT_REF
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
+ && TYPE_VIRTUAL_P (TREE_TYPE (exp))
+ && ! resolves_to_fixed_type_p (exp, &nonnull)
+ && ! nonnull)
+ {
+ exp = stabilize_reference (exp);
+ cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0));
+ }
+
+ exp = get_tinfo_fn_dynamic (exp);
+
+ if (exp == error_mark_node)
+ return error_mark_node;
+
+ exp = build_call (exp, type, NULL_TREE);
+
+ if (cond)
+ {
+ tree bad = throw_bad_typeid ();
+
+ bad = build_compound_expr
+ (expr_tree_cons (NULL_TREE, bad, build_expr_list
+ (NULL_TREE, cp_convert (type, integer_zero_node))));
+ exp = build (COND_EXPR, type, cond, exp, bad);
+ }
+
+ return convert_from_reference (exp);
+}
+
+static tree
+get_tinfo_var (type)
+ tree type;
+{
+ tree tname = build_overload_with_type (get_identifier ("__ti"), type);
+ tree tdecl, arrtype;
+ int size;
+
+ if (IDENTIFIER_GLOBAL_VALUE (tname))
+ return IDENTIFIER_GLOBAL_VALUE (tname);
+
+ /* Figure out how much space we need to allocate for the type_info object.
+ If our struct layout or the type_info classes are changed, this will
+ need to be modified. */
+ if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
+ size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
+ else if (TREE_CODE (type) == POINTER_TYPE
+ && ! (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
+ || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))
+ size = 3 * POINTER_SIZE;
+ else if (IS_AGGR_TYPE (type))
+ {
+ if (CLASSTYPE_N_BASECLASSES (type) == 0)
+ size = 2 * POINTER_SIZE;
+ else if (! TYPE_USES_COMPLEX_INHERITANCE (type)
+ && (TREE_VIA_PUBLIC
+ (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
+ size = 3 * POINTER_SIZE;
+ else
+ size = 3 * POINTER_SIZE + TYPE_PRECISION (sizetype);
+ }
+ else
+ size = 2 * POINTER_SIZE;
+
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+
+ /* The type for a character array of the appropriate size. */
+ arrtype = build_cplus_array_type
+ (unsigned_char_type_node,
+ build_index_type (size_int (size / BITS_PER_UNIT - 1)));
+
+ tdecl = build_decl (VAR_DECL, tname, arrtype);
+ TREE_PUBLIC (tdecl) = 1;
+ DECL_EXTERNAL (tdecl) = 1;
+ DECL_ARTIFICIAL (tdecl) = 1;
+ pushdecl_top_level (tdecl);
+ cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
+
+ pop_obstacks ();
+
+ return tdecl;
+}
+
+tree
+get_tinfo_fn (type)
+ tree type;
+{
+ tree name;
+ tree d;
+
+ if (TREE_CODE (type) == OFFSET_TYPE)
+ type = TREE_TYPE (type);
+ if (TREE_CODE (type) == METHOD_TYPE)
+ type = build_function_type (TREE_TYPE (type),
+ TREE_CHAIN (TYPE_ARG_TYPES (type)));
+
+ name = build_overload_with_type (tinfo_fn_id, type);
+
+ if (IDENTIFIER_GLOBAL_VALUE (name))
+ return IDENTIFIER_GLOBAL_VALUE (name);
+
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+
+ d = build_lang_decl (FUNCTION_DECL, name, tinfo_fn_type);
+ DECL_EXTERNAL (d) = 1;
+ TREE_PUBLIC (d) = 1;
+ DECL_ARTIFICIAL (d) = 1;
+ DECL_NOT_REALLY_EXTERN (d) = 1;
+ DECL_MUTABLE_P (d) = 1;
+ TREE_TYPE (name) = copy_to_permanent (type);
+ pushdecl_top_level (d);
+ make_function_rtl (d);
+ assemble_external (d);
+ mark_inline_for_output (d);
+ if (at_eof)
+ import_export_decl (d);
+
+ pop_obstacks ();
+
+ return d;
+}
+
+static tree
+get_typeid_1 (type)
+ tree type;
+{
+ tree t = build_call
+ (get_tinfo_fn (type), TREE_TYPE (tinfo_fn_type), NULL_TREE);
+ return convert_from_reference (t);
+}
+
+/* Return the type_info object for TYPE, creating it if necessary. */
+
+tree
+get_typeid (type)
+ tree type;
+{
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ if (processing_template_decl)
+ return build_min_nt (TYPEID_EXPR, type);
+
+ /* If the type of the type-id is a reference type, the result of the
+ typeid expression refers to a type_info object representing the
+ referenced type. */
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ type = TREE_TYPE (type);
+
+ /* The top-level cv-qualifiers of the lvalue expression or the type-id
+ that is the operand of typeid are always ignored. */
+ type = TYPE_MAIN_VARIANT (type);
+
+ return get_typeid_1 (type);
+}
+
+/* Check whether TEST is null before returning RESULT. If TEST is used in
+ RESULT, it must have previously had a save_expr applied to it. */
+
+static tree
+ifnonnull (test, result)
+ tree test, result;
+{
+ return build (COND_EXPR, TREE_TYPE (result),
+ build (EQ_EXPR, boolean_type_node, test, integer_zero_node),
+ cp_convert (TREE_TYPE (result), integer_zero_node),
+ result);
+}
+
+/* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
+ paper. */
+
+static tree
+build_dynamic_cast_1 (type, expr)
+ tree type, expr;
+{
+ enum tree_code tc = TREE_CODE (type);
+ tree exprtype = TREE_TYPE (expr);
+ enum tree_code ec;
+ tree dcast_fn;
+
+ if (type == error_mark_node || expr == error_mark_node)
+ return error_mark_node;
+
+ if (processing_template_decl)
+ {
+ tree t = build_min (DYNAMIC_CAST_EXPR, type, expr);
+ return t;
+ }
+
+ assert (exprtype != NULL_TREE);
+ ec = TREE_CODE (exprtype);
+
+ switch (tc)
+ {
+ case POINTER_TYPE:
+ if (ec == REFERENCE_TYPE)
+ {
+ expr = convert_from_reference (expr);
+ exprtype = TREE_TYPE (expr);
+ ec = TREE_CODE (exprtype);
+ }
+ if (ec != POINTER_TYPE)
+ goto fail;
+ if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
+ goto fail;
+ if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
+ goto fail;
+ if (TREE_READONLY (TREE_TYPE (exprtype))
+ && ! TYPE_READONLY (TREE_TYPE (type)))
+ goto fail;
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
+ break;
+ /* else fall through */
+ case REFERENCE_TYPE:
+ if (TREE_CODE (TREE_TYPE (type)) != RECORD_TYPE)
+ goto fail;
+ if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
+ goto fail;
+ break;
+ /* else fall through */
+ default:
+ goto fail;
+ }
+
+ /* Apply trivial conversion T -> T& for dereferenced ptrs. */
+ if (ec == RECORD_TYPE)
+ {
+ exprtype = build_type_variant (exprtype, TREE_READONLY (expr),
+ TREE_THIS_VOLATILE (expr));
+ exprtype = build_reference_type (exprtype);
+ expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
+ LOOKUP_NORMAL, NULL_TREE);
+ ec = REFERENCE_TYPE;
+ }
+
+ if (tc == REFERENCE_TYPE)
+ {
+ if (ec != REFERENCE_TYPE)
+ goto fail;
+ if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
+ goto fail;
+ if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
+ goto fail;
+ if (TREE_READONLY (TREE_TYPE (exprtype))
+ && ! TYPE_READONLY (TREE_TYPE (type)))
+ goto fail;
+ }
+
+ /* If *type is an unambiguous accessible base class of *exprtype,
+ convert statically. */
+ {
+ int distance;
+ tree path;
+
+ distance = get_base_distance (TREE_TYPE (type), TREE_TYPE (exprtype), 1,
+ &path);
+ if (distance >= 0)
+ return build_vbase_path (PLUS_EXPR, type, expr, path, 0);
+ }
+
+ /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
+ if (TYPE_VIRTUAL_P (TREE_TYPE (exprtype)))
+ {
+ tree expr1;
+ /* if TYPE is `void *', return pointer to complete object. */
+ if (tc == POINTER_TYPE
+ && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
+ {
+ /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
+ if (TREE_CODE (expr) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (expr, 0)) == VAR_DECL
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE)
+ return build1 (NOP_EXPR, type, expr);
+
+ /* Since expr is used twice below, save it. */
+ expr = save_expr (expr);
+
+ expr1 = build_headof (expr);
+ if (TREE_TYPE (expr1) != type)
+ expr1 = build1 (NOP_EXPR, type, expr1);
+ return ifnonnull (expr, expr1);
+ }
+ else
+ {
+ tree retval;
+ tree result, td1, td2, td3, elems, expr2;
+
+ /* If we got here, we can't convert statically. Therefore,
+ dynamic_cast<D&>(b) (b an object) cannot succeed. */
+ if (ec == REFERENCE_TYPE)
+ {
+ if (TREE_CODE (expr) == VAR_DECL
+ && TREE_CODE (TREE_TYPE (expr)) == RECORD_TYPE)
+ {
+ cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
+ expr, type);
+ return throw_bad_cast ();
+ }
+ }
+ /* Ditto for dynamic_cast<D*>(&b). */
+ else if (TREE_CODE (expr) == ADDR_EXPR)
+ {
+ tree op = TREE_OPERAND (expr, 0);
+ if (TREE_CODE (op) == VAR_DECL
+ && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
+ {
+ cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
+ expr, type);
+ retval = build_int_2 (0, 0);
+ TREE_TYPE (retval) = type;
+ return retval;
+ }
+ }
+
+ /* Since expr is used twice below, save it. */
+ expr = save_expr (expr);
+
+ expr1 = expr;
+ if (tc == REFERENCE_TYPE)
+ expr1 = build_unary_op (ADDR_EXPR, expr1, 0);
+
+ /* Build run-time conversion. */
+ expr2 = build_headof (expr1);
+
+ if (ec == POINTER_TYPE)
+ td1 = get_tinfo_fn_dynamic (build_indirect_ref (expr, NULL_PTR));
+ else
+ td1 = get_tinfo_fn_dynamic (expr);
+ td1 = decay_conversion (td1);
+
+ td2 = decay_conversion
+ (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (type))));
+ td3 = decay_conversion
+ (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (exprtype))));
+
+ elems = tree_cons
+ (NULL_TREE, td1, tree_cons
+ (NULL_TREE, td2, tree_cons
+ (NULL_TREE, build_int_2 (1, 0), tree_cons
+ (NULL_TREE, expr2, tree_cons
+ (NULL_TREE, td3, tree_cons
+ (NULL_TREE, expr1, NULL_TREE))))));
+
+ dcast_fn = get_identifier ("__dynamic_cast");
+ if (IDENTIFIER_GLOBAL_VALUE (dcast_fn))
+ dcast_fn = IDENTIFIER_GLOBAL_VALUE (dcast_fn);
+ else
+ {
+ tree tmp;
+
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ tmp = tree_cons
+ (NULL_TREE, TREE_TYPE (td1), tree_cons
+ (NULL_TREE, TREE_TYPE (td1), tree_cons
+ (NULL_TREE, integer_type_node, tree_cons
+ (NULL_TREE, ptr_type_node, tree_cons
+ (NULL_TREE, TREE_TYPE (td1), tree_cons
+ (NULL_TREE, ptr_type_node, void_list_node))))));
+ tmp = build_function_type (ptr_type_node, tmp);
+ dcast_fn = build_lang_decl (FUNCTION_DECL, dcast_fn, tmp);
+ DECL_EXTERNAL (dcast_fn) = 1;
+ TREE_PUBLIC (dcast_fn) = 1;
+ DECL_ARTIFICIAL (dcast_fn) = 1;
+ pushdecl_top_level (dcast_fn);
+ make_function_rtl (dcast_fn);
+ assemble_external (dcast_fn);
+ pop_obstacks ();
+ }
+
+ result = build_call
+ (dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems);
+
+ if (tc == REFERENCE_TYPE)
+ {
+ expr1 = throw_bad_cast ();
+ expr1 = build_compound_expr
+ (expr_tree_cons (NULL_TREE, expr1,
+ build_expr_list (NULL_TREE, cp_convert (type, integer_zero_node))));
+ TREE_TYPE (expr1) = type;
+ result = save_expr (result);
+ return build (COND_EXPR, type, result, result, expr1);
+ }
+
+ /* Now back to the type we want from a void*. */
+ result = cp_convert (type, result);
+ return ifnonnull (expr, result);
+ }
+ }
+
+ fail:
+ cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
+ expr, exprtype, type);
+ return error_mark_node;
+}
+
+tree
+build_dynamic_cast (type, expr)
+ tree type, expr;
+{
+ return convert_from_reference (build_dynamic_cast_1 (type, expr));
+}
+
+/* Build and initialize various sorts of descriptors. Every descriptor
+ node has a name associated with it (the name created by mangling).
+ For this reason, we use the identifier as our access to the __*_desc
+ nodes, instead of sticking them directly in the types. Otherwise we
+ would burden all built-in types (and pointer types) with slots that
+ we don't necessarily want to use.
+
+ For each descriptor we build, we build a variable that contains
+ the descriptor's information. When we need this info at runtime,
+ all we need is access to these variables.
+
+ Note: these constructors always return the address of the descriptor
+ info, since that is simplest for their mutual interaction. */
+
+extern tree const_string_type_node;
+
+/* Build an initializer for a __si_type_info node. */
+
+static void
+expand_si_desc (tdecl, type)
+ tree tdecl;
+ tree type;
+{
+ tree t, elems, fn;
+ char *name = build_overload_name (type, 1, 1);
+ tree name_string = combine_strings (build_string (strlen (name)+1, name));
+
+ type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0));
+ expand_expr_stmt (get_typeid_1 (type));
+ t = decay_conversion (get_tinfo_var (type));
+ elems = tree_cons
+ (NULL_TREE, decay_conversion (tdecl), tree_cons
+ (NULL_TREE, decay_conversion (name_string), tree_cons
+ (NULL_TREE, t, NULL_TREE)));
+
+ fn = get_identifier ("__rtti_si");
+ if (IDENTIFIER_GLOBAL_VALUE (fn))
+ fn = IDENTIFIER_GLOBAL_VALUE (fn);
+ else
+ {
+ tree tmp;
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ tmp = tree_cons
+ (NULL_TREE, ptr_type_node, tree_cons
+ (NULL_TREE, const_string_type_node, tree_cons
+ (NULL_TREE, build_pointer_type (type_info_type_node),
+ void_list_node)));
+ tmp = build_function_type (void_type_node, tmp);
+
+ fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
+ DECL_EXTERNAL (fn) = 1;
+ TREE_PUBLIC (fn) = 1;
+ DECL_ARTIFICIAL (fn) = 1;
+ pushdecl_top_level (fn);
+ make_function_rtl (fn);
+ assemble_external (fn);
+ pop_obstacks ();
+ }
+
+ fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
+ expand_expr_stmt (fn);
+}
+
+/* Build an initializer for a __class_type_info node. */
+
+static void
+expand_class_desc (tdecl, type)
+ tree tdecl;
+ tree type;
+{
+ tree name_string;
+ tree fn, tmp;
+ char *name;
+
+ int i = CLASSTYPE_N_BASECLASSES (type);
+ int base_cnt = 0;
+ tree binfos = TYPE_BINFO_BASETYPES (type);
+#if 0
+ /* See code below that used these. */
+ tree vb = CLASSTYPE_VBASECLASSES (type);
+ int n_base = i;
+#endif
+ tree base, elems, access, offset, isvir;
+ tree elt, elts = NULL_TREE;
+ static tree base_info_type_node;
+
+ if (base_info_type_node == NULL_TREE)
+ {
+ tree fields [4];
+
+ /* A reasonably close approximation of __class_type_info::base_info */
+
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ base_info_type_node = make_lang_type (RECORD_TYPE);
+
+ /* Actually const __user_type_info * */
+ fields [0] = build_lang_field_decl
+ (FIELD_DECL, NULL_TREE,
+ build_pointer_type (build_type_variant (type_info_type_node, 1, 0)));
+ fields [1] = build_lang_field_decl
+ (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
+ DECL_BIT_FIELD (fields[1]) = 1;
+ DECL_FIELD_SIZE (fields[1]) = 29;
+
+ fields [2] = build_lang_field_decl
+ (FIELD_DECL, NULL_TREE, boolean_type_node);
+ DECL_BIT_FIELD (fields[2]) = 1;
+ DECL_FIELD_SIZE (fields[2]) = 1;
+
+ /* Actually enum access */
+ fields [3] = build_lang_field_decl
+ (FIELD_DECL, NULL_TREE, integer_type_node);
+ DECL_BIT_FIELD (fields[3]) = 1;
+ DECL_FIELD_SIZE (fields[3]) = 2;
+
+ finish_builtin_type (base_info_type_node, "__base_info", fields,
+ 3, ptr_type_node);
+ pop_obstacks ();
+ }
+
+ while (--i >= 0)
+ {
+ tree binfo = TREE_VEC_ELT (binfos, i);
+
+ expand_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
+ base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo)));
+
+ if (TREE_VIA_VIRTUAL (binfo))
+ {
+ tree t = BINFO_TYPE (binfo);
+ char *name;
+ tree field;
+
+ name = (char *) alloca (TYPE_NAME_LENGTH (t)+sizeof (VBASE_NAME)+1);
+ sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (t));
+ field = lookup_field (type, get_identifier (name), 0, 0);
+ offset = size_binop (FLOOR_DIV_EXPR,
+ DECL_FIELD_BITPOS (field), size_int (BITS_PER_UNIT));
+ }
+ else
+ offset = BINFO_OFFSET (binfo);
+
+ if (TREE_VIA_PUBLIC (binfo))
+ access = access_public_node;
+ else if (TREE_VIA_PROTECTED (binfo))
+ access = access_protected_node;
+ else
+ access = access_private_node;
+ if (TREE_VIA_VIRTUAL (binfo))
+ isvir = boolean_true_node;
+ else
+ isvir = boolean_false_node;
+
+ elt = build
+ (CONSTRUCTOR, base_info_type_node, NULL_TREE, tree_cons
+ (NULL_TREE, base, tree_cons
+ (NULL_TREE, offset, tree_cons
+ (NULL_TREE, isvir, tree_cons
+ (NULL_TREE, access, NULL_TREE)))));
+ TREE_HAS_CONSTRUCTOR (elt) = TREE_CONSTANT (elt) = TREE_STATIC (elt) = 1;
+ elts = expr_tree_cons (NULL_TREE, elt, elts);
+ base_cnt++;
+ }
+#if 0
+ i = n_base;
+ while (vb)
+ {
+ tree b;
+ access = access_public_node;
+ while (--i >= 0)
+ {
+ b = TREE_VEC_ELT (binfos, i);
+ if (BINFO_TYPE (vb) == BINFO_TYPE (b) && TREE_VIA_VIRTUAL (b))
+ {
+ if (TREE_VIA_PUBLIC (b))
+ access = access_public_node;
+ else if (TREE_VIA_PROTECTED (b))
+ access = access_protected_node;
+ else
+ access = access_private_node;
+ break;
+ }
+ }
+ base = build_t_desc (BINFO_TYPE (vb), 1);
+ offset = BINFO_OFFSET (vb);
+ isvir = build_int_2 (1, 0);
+
+ base_list = expr_tree_cons (NULL_TREE, base, base_list);
+ isvir_list = expr_tree_cons (NULL_TREE, isvir, isvir_list);
+ acc_list = expr_tree_cons (NULL_TREE, access, acc_list);
+ off_list = expr_tree_cons (NULL_TREE, offset, off_list);
+
+ base_cnt++;
+ vb = TREE_CHAIN (vb);
+ }
+#endif
+
+ name = build_overload_name (type, 1, 1);
+ name_string = combine_strings (build_string (strlen (name)+1, name));
+
+ {
+ tree arrtype = build_array_type (base_info_type_node, NULL_TREE);
+ elts = build (CONSTRUCTOR, arrtype, NULL_TREE, elts);
+ TREE_HAS_CONSTRUCTOR (elts) = TREE_CONSTANT (elts)
+ = TREE_STATIC (elts) = 1;
+ complete_array_type (arrtype, elts, 1);
+ }
+
+ elems = tree_cons
+ (NULL_TREE, decay_conversion (tdecl), tree_cons
+ (NULL_TREE, decay_conversion (name_string), tree_cons
+ (NULL_TREE, decay_conversion (elts), tree_cons
+ (NULL_TREE, cp_convert (sizetype, build_int_2 (base_cnt, 0)),
+ NULL_TREE))));
+
+ fn = get_identifier ("__rtti_class");
+ if (IDENTIFIER_GLOBAL_VALUE (fn))
+ fn = IDENTIFIER_GLOBAL_VALUE (fn);
+ else
+ {
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ tmp = tree_cons
+ (NULL_TREE, ptr_type_node, tree_cons
+ (NULL_TREE, const_string_type_node, tree_cons
+ (NULL_TREE, build_pointer_type (base_info_type_node), tree_cons
+ (NULL_TREE, sizetype, void_list_node))));
+ tmp = build_function_type (void_type_node, tmp);
+
+ fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
+ DECL_EXTERNAL (fn) = 1;
+ TREE_PUBLIC (fn) = 1;
+ DECL_ARTIFICIAL (fn) = 1;
+ pushdecl_top_level (fn);
+ make_function_rtl (fn);
+ assemble_external (fn);
+ pop_obstacks ();
+ }
+
+ fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
+ expand_expr_stmt (fn);
+}
+
+/* Build an initializer for a __pointer_type_info node. */
+
+static void
+expand_ptr_desc (tdecl, type)
+ tree tdecl;
+ tree type;
+{
+ tree t, elems, fn;
+ char *name = build_overload_name (type, 1, 1);
+ tree name_string = combine_strings (build_string (strlen (name)+1, name));
+
+ type = TREE_TYPE (type);
+ expand_expr_stmt (get_typeid_1 (type));
+ t = decay_conversion (get_tinfo_var (type));
+ elems = tree_cons
+ (NULL_TREE, decay_conversion (tdecl), tree_cons
+ (NULL_TREE, decay_conversion (name_string), tree_cons
+ (NULL_TREE, t, NULL_TREE)));
+
+ fn = get_identifier ("__rtti_ptr");
+ if (IDENTIFIER_GLOBAL_VALUE (fn))
+ fn = IDENTIFIER_GLOBAL_VALUE (fn);
+ else
+ {
+ tree tmp;
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ tmp = tree_cons
+ (NULL_TREE, ptr_type_node, tree_cons
+ (NULL_TREE, const_string_type_node, tree_cons
+ (NULL_TREE, build_pointer_type (type_info_type_node),
+ void_list_node)));
+ tmp = build_function_type (void_type_node, tmp);
+
+ fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
+ DECL_EXTERNAL (fn) = 1;
+ TREE_PUBLIC (fn) = 1;
+ DECL_ARTIFICIAL (fn) = 1;
+ pushdecl_top_level (fn);
+ make_function_rtl (fn);
+ assemble_external (fn);
+ pop_obstacks ();
+ }
+
+ fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
+ expand_expr_stmt (fn);
+}
+
+/* Build an initializer for a __attr_type_info node. */
+
+static void
+expand_attr_desc (tdecl, type)
+ tree tdecl;
+ tree type;
+{
+ tree elems, t, fn;
+ char *name = build_overload_name (type, 1, 1);
+ tree name_string = combine_strings (build_string (strlen (name)+1, name));
+ tree attrval = build_int_2
+ (TYPE_READONLY (type) | TYPE_VOLATILE (type) * 2, 0);
+
+ expand_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
+ t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));
+ elems = tree_cons
+ (NULL_TREE, decay_conversion (tdecl), tree_cons
+ (NULL_TREE, decay_conversion (name_string), tree_cons
+ (NULL_TREE, attrval, expr_tree_cons (NULL_TREE, t, NULL_TREE))));
+
+ fn = get_identifier ("__rtti_attr");
+ if (IDENTIFIER_GLOBAL_VALUE (fn))
+ fn = IDENTIFIER_GLOBAL_VALUE (fn);
+ else
+ {
+ tree tmp;
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ tmp = tree_cons
+ (NULL_TREE, ptr_type_node, tree_cons
+ (NULL_TREE, const_string_type_node, tree_cons
+ (NULL_TREE, integer_type_node, tree_cons
+ (NULL_TREE, build_pointer_type (type_info_type_node),
+ void_list_node))));
+ tmp = build_function_type (void_type_node, tmp);
+
+ fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
+ DECL_EXTERNAL (fn) = 1;
+ TREE_PUBLIC (fn) = 1;
+ DECL_ARTIFICIAL (fn) = 1;
+ pushdecl_top_level (fn);
+ make_function_rtl (fn);
+ assemble_external (fn);
+ pop_obstacks ();
+ }
+
+ fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
+ expand_expr_stmt (fn);
+}
+
+/* Build an initializer for a type_info node that just has a name. */
+
+static void
+expand_generic_desc (tdecl, type, fnname)
+ tree tdecl;
+ tree type;
+ char *fnname;
+{
+ char *name = build_overload_name (type, 1, 1);
+ tree name_string = combine_strings (build_string (strlen (name)+1, name));
+ tree elems = tree_cons
+ (NULL_TREE, decay_conversion (tdecl), tree_cons
+ (NULL_TREE, decay_conversion (name_string), NULL_TREE));
+
+ tree fn = get_identifier (fnname);
+ if (IDENTIFIER_GLOBAL_VALUE (fn))
+ fn = IDENTIFIER_GLOBAL_VALUE (fn);
+ else
+ {
+ tree tmp;
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ tmp = tree_cons
+ (NULL_TREE, ptr_type_node, tree_cons
+ (NULL_TREE, const_string_type_node, void_list_node));
+ tmp = build_function_type (void_type_node, tmp);
+
+ fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
+ DECL_EXTERNAL (fn) = 1;
+ TREE_PUBLIC (fn) = 1;
+ DECL_ARTIFICIAL (fn) = 1;
+ pushdecl_top_level (fn);
+ make_function_rtl (fn);
+ assemble_external (fn);
+ pop_obstacks ();
+ }
+
+ fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
+ expand_expr_stmt (fn);
+}
+
+/* Generate the code for a type_info initialization function.
+ Note that we take advantage of the passage
+
+ 5.2.7 Type identification [expr.typeid]
+
+ Whether or not the destructor is called for the type_info object at the
+ end of the program is unspecified.
+
+ and don't bother to arrange for these objects to be destroyed. It
+ doesn't matter, anyway, since the destructors don't do anything.
+
+ This must only be called from toplevel (i.e. from finish_file)! */
+
+void
+synthesize_tinfo_fn (fndecl)
+ tree fndecl;
+{
+ tree type = TREE_TYPE (DECL_NAME (fndecl));
+ tree tmp, addr;
+
+ tree tdecl = get_tinfo_var (type);
+ DECL_EXTERNAL (tdecl) = 0;
+ TREE_STATIC (tdecl) = 1;
+ DECL_COMMON (tdecl) = 1;
+ TREE_USED (tdecl) = 1;
+ DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);
+ cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
+
+ start_function (NULL_TREE, fndecl, NULL_TREE, 1);
+ store_parm_decls ();
+ clear_last_expr ();
+ push_momentary ();
+
+ /* If the first word of the array (the vtable) is non-zero, we've already
+ initialized the object, so don't do it again. */
+ addr = decay_conversion (tdecl);
+ tmp = cp_convert (build_pointer_type (ptr_type_node), addr);
+ tmp = build_indirect_ref (tmp, 0);
+ tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node, 1);
+ expand_start_cond (tmp, 0);
+
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ expand_generic_desc (tdecl, type, "__rtti_func");
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ expand_generic_desc (tdecl, type, "__rtti_array");
+ else if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
+ expand_attr_desc (tdecl, type);
+ else if (TREE_CODE (type) == POINTER_TYPE)
+ {
+ if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
+ expand_generic_desc (tdecl, type, "__rtti_ptmd");
+ else if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
+ expand_generic_desc (tdecl, type, "__rtti_ptmf");
+ else
+ expand_ptr_desc (tdecl, type);
+ }
+ else if (TYPE_PTRMEMFUNC_P (type))
+ expand_generic_desc (tdecl, type, "__rtti_ptmf");
+ else if (IS_AGGR_TYPE (type))
+ {
+ if (CLASSTYPE_N_BASECLASSES (type) == 0)
+ expand_generic_desc (tdecl, type, "__rtti_user");
+ else if (! TYPE_USES_COMPLEX_INHERITANCE (type)
+ && (TREE_VIA_PUBLIC
+ (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
+ expand_si_desc (tdecl, type);
+ else
+ expand_class_desc (tdecl, type);
+ }
+ else if (TREE_CODE (type) == ENUMERAL_TYPE)
+ expand_generic_desc (tdecl, type, "__rtti_user");
+ else
+ my_friendly_abort (252);
+
+ expand_end_cond ();
+
+ /* OK, now return the type_info object. */
+ tmp = cp_convert (build_pointer_type (type_info_type_node), addr);
+ tmp = build_indirect_ref (tmp, 0);
+ c_expand_return (tmp);
+ finish_function (lineno, 0, 0);
+}
+
+#if 0
+/* This is the old dossier type descriptor generation code, it's much
+ more extended than rtti. It's reserved for later use. */
+/* Build an initializer for a __t_desc node. So that we can take advantage
+ of recursion, we accept NULL for TYPE.
+ DEFINITION is greater than zero iff we must define the type descriptor
+ (as opposed to merely referencing it). 1 means treat according to
+ #pragma interface/#pragma implementation rules. 2 means define as
+ global and public, no matter what. */
+
+tree
+build_t_desc (type, definition)
+ tree type;
+ int definition;
+{
+ tree tdecl;
+ tree tname, name_string;
+ tree elems, fields;
+ tree parents, vbases, offsets, ivars, methods, target_type;
+ int method_count = 0, field_count = 0;
+
+ if (type == NULL_TREE)
+ return NULL_TREE;
+
+ tname = build_t_desc_overload (type);
+ if (IDENTIFIER_AS_DESC (tname)
+ && (!definition || TREE_ASM_WRITTEN (IDENTIFIER_AS_DESC (tname))))
+ return IDENTIFIER_AS_DESC (tname);
+
+ tdecl = lookup_name (tname, 0);
+ if (tdecl == NULL_TREE)
+ {
+ tdecl = build_decl (VAR_DECL, tname, __t_desc_type_node);
+ DECL_EXTERNAL (tdecl) = 1;
+ TREE_PUBLIC (tdecl) = 1;
+ tdecl = pushdecl_top_level (tdecl);
+ }
+ /* If we previously defined it, return the defined result. */
+ else if (definition && DECL_INITIAL (tdecl))
+ return IDENTIFIER_AS_DESC (tname);
+
+ if (definition)
+ {
+ tree taggr = type;
+ /* Let T* and T& be written only when T is written (if T is an aggr).
+ We do this for const, but not for volatile, since volatile
+ is rare and const is not. */
+ if (!TYPE_VOLATILE (taggr)
+ && (TREE_CODE (taggr) == POINTER_TYPE
+ || TREE_CODE (taggr) == REFERENCE_TYPE)
+ && IS_AGGR_TYPE (TREE_TYPE (taggr)))
+ taggr = TREE_TYPE (taggr);
+
+ /* If we know that we don't need to write out this type's
+ vtable, then don't write out it's dossier. Somebody
+ else will take care of that. */
+ if (IS_AGGR_TYPE (taggr) && CLASSTYPE_VFIELD (taggr))
+ {
+ if (CLASSTYPE_VTABLE_NEEDS_WRITING (taggr))
+ {
+ TREE_PUBLIC (tdecl) = ! CLASSTYPE_INTERFACE_ONLY (taggr)
+ && CLASSTYPE_INTERFACE_KNOWN (taggr);
+ DECL_EXTERNAL (tdecl) = 0;
+ }
+ else
+ {
+ if (write_virtuals != 0)
+ TREE_PUBLIC (tdecl) = 1;
+ }
+ }
+ else
+ {
+ DECL_EXTERNAL (tdecl) = 0;
+ TREE_PUBLIC (tdecl) = (definition > 1);
+ }
+ }
+ SET_IDENTIFIER_AS_DESC (tname, build_unary_op (ADDR_EXPR, tdecl, 0));
+
+ if (!definition || DECL_EXTERNAL (tdecl))
+ {
+ /* That's it! */
+ cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
+ return IDENTIFIER_AS_DESC (tname);
+ }
+
+ /* Show that we are defining the t_desc for this type. */
+ DECL_INITIAL (tdecl) = error_mark_node;
+
+ parents = build_expr_list (NULL_TREE, integer_zero_node);
+ vbases = build_expr_list (NULL_TREE, integer_zero_node);
+ offsets = build_expr_list (NULL_TREE, integer_zero_node);
+ methods = NULL_TREE;
+ ivars = NULL_TREE;
+
+ if (TYPE_LANG_SPECIFIC (type))
+ {
+ int i = CLASSTYPE_N_BASECLASSES (type);
+ tree method_vec = CLASSTYPE_METHOD_VEC (type);
+ tree *meth, *end;
+ tree binfos = TYPE_BINFO_BASETYPES (type);
+ tree vb = CLASSTYPE_VBASECLASSES (type);
+
+ while (--i >= 0)
+ parents = tree_cons (NULL_TREE, build_t_desc (BINFO_TYPE (TREE_VEC_ELT (binfos, i)), 0), parents);
+
+ while (vb)
+ {
+ vbases = tree_cons (NULL_TREE, build_t_desc (BINFO_TYPE (vb), 0), vbases);
+ offsets = tree_cons (NULL_TREE, BINFO_OFFSET (vb), offsets);
+ vb = TREE_CHAIN (vb);
+ }
+
+ if (method_vec)
+ for (meth = TREE_VEC_END (method_vec),
+ end = &TREE_VEC_ELT (method_vec, 0); meth-- != end; )
+ if (*meth)
+ {
+ methods = tree_cons (NULL_TREE, build_m_desc (*meth), methods);
+ method_count++;
+ }
+ }
+
+ if (IS_AGGR_TYPE (type))
+ {
+ for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
+ if (TREE_CODE (fields) == FIELD_DECL
+ || TREE_CODE (fields) == VAR_DECL)
+ {
+ ivars = tree_cons (NULL_TREE, build_i_desc (fields), ivars);
+ field_count++;
+ }
+ ivars = nreverse (ivars);
+ }
+
+ parents = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node), parents, 0);
+ vbases = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node), vbases, 0);
+ offsets = finish_table (NULL_TREE, integer_type_node, offsets, 0);
+ if (methods == NULL_TREE)
+ methods = null_pointer_node;
+ else
+ methods = build_unary_op (ADDR_EXPR,
+ finish_table (NULL_TREE, __m_desc_type_node, methods, 0),
+ 0);
+ if (ivars == NULL_TREE)
+ ivars = null_pointer_node;
+ else
+ ivars = build_unary_op (ADDR_EXPR,
+ finish_table (NULL_TREE, __i_desc_type_node, ivars, 0),
+ 0);
+ if (TREE_TYPE (type))
+ target_type = build_t_desc (TREE_TYPE (type), definition);
+ else
+ target_type = integer_zero_node;
+
+ name_string = combine_strings (build_string (IDENTIFIER_LENGTH (tname)+1, IDENTIFIER_POINTER (tname)));
+
+ elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),
+ tree_cons (NULL_TREE,
+ TYPE_SIZE(type)? size_in_bytes(type) : integer_zero_node,
+ /* really should use bitfield initialization here. */
+ tree_cons (NULL_TREE, integer_zero_node,
+ tree_cons (NULL_TREE, target_type,
+ tree_cons (NULL_TREE, build_int_2 (field_count, 2),
+ tree_cons (NULL_TREE, build_int_2 (method_count, 2),
+ tree_cons (NULL_TREE, ivars,
+ tree_cons (NULL_TREE, methods,
+ tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, parents, 0),
+ tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, vbases, 0),
+ build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, offsets, 0))))))))))));
+ return build_generic_desc (tdecl, elems);
+}
+
+/* Build an initializer for a __i_desc node. */
+
+tree
+build_i_desc (decl)
+ tree decl;
+{
+ tree elems, name_string;
+ tree taggr;
+
+ name_string = DECL_NAME (decl);
+ name_string = combine_strings (build_string (IDENTIFIER_LENGTH (name_string)+1, IDENTIFIER_POINTER (name_string)));
+
+ /* Now decide whether this ivar should cause it's type to get
+ def'd or ref'd in this file. If the type we are looking at
+ has a proxy definition, we look at the proxy (i.e., a
+ `foo *' is equivalent to a `foo'). */
+ taggr = TREE_TYPE (decl);
+
+ if ((TREE_CODE (taggr) == POINTER_TYPE
+ || TREE_CODE (taggr) == REFERENCE_TYPE)
+ && TYPE_VOLATILE (taggr) == 0)
+ taggr = TREE_TYPE (taggr);
+
+ elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),
+ tree_cons (NULL_TREE, DECL_FIELD_BITPOS (decl),
+ build_tree_list (NULL_TREE, build_t_desc (TREE_TYPE (decl),
+ ! IS_AGGR_TYPE (taggr)))));
+ taggr = build (CONSTRUCTOR, __i_desc_type_node, NULL_TREE, elems);
+ TREE_CONSTANT (taggr) = 1;
+ TREE_STATIC (taggr) = 1;
+ TREE_READONLY (taggr) = 1;
+ return taggr;
+}
+
+/* Build an initializer for a __m_desc node. */
+
+tree
+build_m_desc (decl)
+ tree decl;
+{
+ tree taggr, elems, name_string;
+ tree parm_count, req_count, vindex, vcontext;
+ tree parms;
+ int p_count, r_count;
+ tree parm_types = NULL_TREE;
+
+ for (parms = TYPE_ARG_TYPES (TREE_TYPE (decl)), p_count = 0, r_count = 0;
+ parms != NULL_TREE; parms = TREE_CHAIN (parms), p_count++)
+ {
+ taggr = TREE_VALUE (parms);
+ if ((TREE_CODE (taggr) == POINTER_TYPE
+ || TREE_CODE (taggr) == REFERENCE_TYPE)
+ && TYPE_VOLATILE (taggr) == 0)
+ taggr = TREE_TYPE (taggr);
+
+ parm_types = tree_cons (NULL_TREE, build_t_desc (TREE_VALUE (parms),
+ ! IS_AGGR_TYPE (taggr)),
+ parm_types);
+ if (TREE_PURPOSE (parms) == NULL_TREE)
+ r_count++;
+ }
+
+ parm_types = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node),
+ nreverse (parm_types), 0);
+ parm_count = build_int_2 (p_count, 0);
+ req_count = build_int_2 (r_count, 0);
+
+ if (DECL_VINDEX (decl))
+ vindex = DECL_VINDEX (decl);
+ else
+ vindex = integer_zero_node;
+ if (DECL_CONTEXT (decl)
+ && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
+ vcontext = build_t_desc (DECL_CONTEXT (decl), 0);
+ else
+ vcontext = integer_zero_node;
+ name_string = DECL_NAME (decl);
+ if (name_string == NULL)
+ name_string = DECL_ASSEMBLER_NAME (decl);
+ name_string = combine_strings (build_string (IDENTIFIER_LENGTH (name_string)+1, IDENTIFIER_POINTER (name_string)));
+
+ /* Now decide whether the return type of this mvar
+ should cause it's type to get def'd or ref'd in this file.
+ If the type we are looking at has a proxy definition,
+ we look at the proxy (i.e., a `foo *' is equivalent to a `foo'). */
+ taggr = TREE_TYPE (TREE_TYPE (decl));
+
+ if ((TREE_CODE (taggr) == POINTER_TYPE
+ || TREE_CODE (taggr) == REFERENCE_TYPE)
+ && TYPE_VOLATILE (taggr) == 0)
+ taggr = TREE_TYPE (taggr);
+
+ elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),
+ tree_cons (NULL_TREE, vindex,
+ tree_cons (NULL_TREE, vcontext,
+ tree_cons (NULL_TREE, build_t_desc (TREE_TYPE (TREE_TYPE (decl)),
+ ! IS_AGGR_TYPE (taggr)),
+ tree_cons (NULL_TREE, build_c_cast (build_pointer_type (default_function_type), build_unary_op (ADDR_EXPR, decl, 0)),
+ tree_cons (NULL_TREE, parm_count,
+ tree_cons (NULL_TREE, req_count,
+ build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, parm_types, 0)))))))));
+
+ taggr = build (CONSTRUCTOR, __m_desc_type_node, NULL_TREE, elems);
+ TREE_CONSTANT (taggr) = 1;
+ TREE_STATIC (taggr) = 1;
+ TREE_READONLY (taggr) = 1;
+ return taggr;
+}
+#endif /* dossier */
diff --git a/gnu/usr.bin/gcc/cp/tinfo.cc b/gnu/usr.bin/gcc/cp/tinfo.cc
new file mode 100644
index 00000000000..d82aaaf0431
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/tinfo.cc
@@ -0,0 +1,125 @@
+// Methods for type_info for -*- C++ -*- Run Time Type Identification.
+// Copyright (C) 1994, 1996 Free Software Foundation
+
+// 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.
+
+// As a special exception, if you link this library with other files,
+// some of which are compiled with GCC, to produce an executable,
+// this library does not by itself 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.
+
+#include <stddef.h>
+#include "tinfo.h"
+#include "new" // for placement new
+
+// This file contains the minimal working set necessary to link with code
+// that uses virtual functions and -frtti but does not actually use RTTI
+// functionality.
+
+type_info::
+~type_info ()
+{ }
+
+extern "C" void
+__rtti_class (void *addr, const char *name,
+ const __class_type_info::base_info *bl, size_t bn)
+{ new (addr) __class_type_info (name, bl, bn); }
+
+extern "C" void
+__rtti_si (void *addr, const char *n, const type_info *ti)
+{
+ new (addr) __si_type_info
+ (n, static_cast <const __user_type_info &> (*ti));
+}
+
+extern "C" void
+__rtti_user (void *addr, const char *name)
+{ new (addr) __user_type_info (name); }
+
+// dynamic_cast helper methods.
+// Returns a pointer to the desired sub-object or 0.
+
+void * __user_type_info::
+dcast (const type_info& to, int, void *addr, const type_info *, void *) const
+{ return (*this == to) ? addr : 0; }
+
+void * __si_type_info::
+dcast (const type_info& to, int require_public, void *addr,
+ const type_info *sub, void *subptr) const
+{
+ if (*this == to)
+ return addr;
+ return base.dcast (to, require_public, addr, sub, subptr);
+}
+
+void* __class_type_info::
+dcast (const type_info& desired, int is_public, void *objptr,
+ const type_info *sub, void *subptr) const
+{
+ if (*this == desired)
+ return objptr;
+
+ void *match_found = 0;
+ for (int i = 0; i < n_bases; i++)
+ {
+ if (is_public && base_list[i].access != PUBLIC)
+ continue;
+
+ void *p = (char *)objptr + base_list[i].offset;
+ if (base_list[i].is_virtual)
+ p = *(void **)p;
+ p = base_list[i].base->dcast (desired, is_public, p, sub, subptr);
+ if (p)
+ {
+ if (match_found == 0)
+ match_found = p;
+ else if (match_found != p)
+ {
+ if (sub)
+ {
+ // Perhaps we're downcasting from *sub to desired; see if
+ // subptr is a subobject of exactly one of {match_found,p}.
+
+ const __user_type_info &d =
+ static_cast <const __user_type_info &> (desired);
+
+ void *os = d.dcast (*sub, 1, match_found);
+ void *ns = d.dcast (*sub, 1, p);
+
+ if (os == ns)
+ /* ambiguous -- subptr is a virtual base */;
+ else if (os == subptr)
+ continue;
+ else if (ns == subptr)
+ {
+ match_found = p;
+ continue;
+ }
+ }
+
+ // base found at two different pointers,
+ // conversion is not unique
+ return 0;
+ }
+ }
+ }
+
+ return match_found;
+}
diff --git a/gnu/usr.bin/gcc/cp/tinfo.h b/gnu/usr.bin/gcc/cp/tinfo.h
new file mode 100644
index 00000000000..3df55a5c709
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/tinfo.h
@@ -0,0 +1,55 @@
+// RTTI support internals for -*- C++ -*-
+// Copyright (C) 1994, 1995, 1996 Free Software Foundation
+
+#include "typeinfo"
+
+// Class declarations shared between the typeinfo implementation files.
+
+// type_info for a class with no base classes (or an enum).
+
+struct __user_type_info : public type_info {
+ __user_type_info (const char *n) : type_info (n) {}
+
+ // If our type can be converted to the desired type,
+ // return the pointer, adjusted accordingly; else return 0.
+ virtual void* dcast (const type_info &, int, void *,
+ const type_info * = 0, void * = 0) const;
+};
+
+// type_info for a class with one public, nonvirtual base class.
+
+class __si_type_info : public __user_type_info {
+ const __user_type_info &base;
+
+public:
+ __si_type_info (const char *n, const __user_type_info &b)
+ : __user_type_info (n), base (b) { }
+
+ virtual void *dcast (const type_info &, int, void *,
+ const type_info * = 0, void * = 0) const;
+};
+
+// type_info for a general class.
+
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+
+struct __class_type_info : public __user_type_info {
+ enum access { PUBLIC = 1, PROTECTED = 2, PRIVATE = 3 };
+
+ struct base_info {
+ const __user_type_info *base;
+ USItype offset: 29;
+ bool is_virtual: 1;
+ access access: 2;
+ };
+
+ const base_info *base_list;
+ size_t n_bases;
+
+ __class_type_info (const char *name, const base_info *bl, size_t bn)
+ : __user_type_info (name), base_list (bl), n_bases (bn) {}
+
+ // This is a little complex.
+ virtual void* dcast (const type_info &, int, void *,
+ const type_info * = 0, void * = 0) const;
+};
diff --git a/gnu/usr.bin/gcc/cp/tinfo2.cc b/gnu/usr.bin/gcc/cp/tinfo2.cc
new file mode 100644
index 00000000000..128661c1cd2
--- /dev/null
+++ b/gnu/usr.bin/gcc/cp/tinfo2.cc
@@ -0,0 +1,323 @@
+// Methods for type_info for -*- C++ -*- Run Time Type Identification.
+// Copyright (C) 1994, 1996 Free Software Foundation
+
+// 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.
+
+// As a special exception, if you link this library with other files,
+// some of which are compiled with GCC, to produce an executable,
+// this library does not by itself 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.
+
+#include <stddef.h>
+#include "tinfo.h"
+#include "new" // for placement new
+
+// service function for comparing types by name.
+
+static inline int
+fast_compare (const char *n1, const char *n2) {
+ int c;
+ if (n1 == n2) return 0;
+ if (n1 == 0) return *n2;
+ else if (n2 == 0) return *n1;
+
+ c = (int)*n1++ - (int)*n2++;
+ return c == 0 ? strcmp (n1, n2) : c;
+};
+
+bool
+type_info::before (const type_info &arg) const
+{
+ return fast_compare (name (), arg.name ()) < 0;
+}
+
+#ifdef _WIN32
+bool type_info::
+operator== (const type_info& arg) const
+{
+ return fast_compare (name (), arg.name ()) == 0;
+}
+
+bool type_info::
+operator!= (const type_info& arg) const
+{
+ return fast_compare (name (), arg.name ()) != 0;
+}
+#endif
+
+// type info for pointer type.
+
+struct __pointer_type_info : public type_info {
+ const type_info& type;
+
+ __pointer_type_info (const char *n, const type_info& ti)
+ : type_info (n), type (ti) {}
+};
+
+// type info for attributes
+
+struct __attr_type_info : public type_info {
+ enum cv { NONE = 0, CONST = 1, VOLATILE = 2, CONSTVOL = 1 | 2 };
+
+ const type_info& type;
+ cv attr;
+
+ __attr_type_info (const char *n, cv a, const type_info& t)
+ : type_info (n), type (t), attr (a) {}
+};
+
+// type_info for builtin type
+
+struct __builtin_type_info : public type_info {
+ __builtin_type_info (const char *n): type_info (n) {}
+};
+
+// type info for function.
+
+struct __func_type_info : public type_info {
+ __func_type_info (const char *n) : type_info (n) {}
+};
+
+// type info for pointer to member function.
+
+struct __ptmf_type_info : public type_info {
+ __ptmf_type_info (const char *n) : type_info (n) {}
+};
+
+// type info for pointer to data member.
+
+struct __ptmd_type_info : public type_info {
+ __ptmd_type_info (const char *n): type_info (n) {}
+};
+
+// type info for array.
+
+struct __array_type_info : public type_info {
+ __array_type_info (const char *n): type_info (n) {}
+};
+
+// Entry points for the compiler.
+
+/* Low level match routine used by compiler to match types of catch
+ variables and thrown objects. */
+
+extern "C" void*
+__throw_type_match_rtti (void *catch_type_r, void *throw_type_r, void *objptr)
+{
+ const type_info &catch_type = *(const type_info *)catch_type_r;
+ const type_info &throw_type = *(const type_info *)throw_type_r;
+
+ if (catch_type == throw_type)
+ return objptr;
+
+#if 0
+ printf ("We want to match a %s against a %s!\n",
+ throw_type.name (), catch_type.name ());
+#endif
+
+ void *new_objptr = 0;
+
+ if (const __user_type_info *p
+ = dynamic_cast <const __user_type_info *> (&throw_type))
+ {
+ /* The 1 skips conversions to private bases. */
+ new_objptr = p->dcast (catch_type, 1, objptr);
+ }
+ else if (const __pointer_type_info *fr =
+ dynamic_cast <const __pointer_type_info *> (&throw_type))
+ {
+ const __pointer_type_info *to =
+ dynamic_cast <const __pointer_type_info *> (&catch_type);
+
+ if (! to)
+ goto fail;
+
+ const type_info *subfr = &fr->type, *subto = &to->type;
+ __attr_type_info::cv cvfrom, cvto;
+
+ if (const __attr_type_info *at
+ = dynamic_cast <const __attr_type_info *> (subfr))
+ {
+ cvfrom = at->attr;
+ subfr = &at->type;
+ }
+ else
+ cvfrom = __attr_type_info::NONE;
+
+ if (const __attr_type_info *at
+ = dynamic_cast <const __attr_type_info *> (subto))
+ {
+ cvto = at->attr;
+ subto = &at->type;
+ }
+ else
+ cvto = __attr_type_info::NONE;
+
+ if (((cvfrom & __attr_type_info::CONST)
+ > (cvto & __attr_type_info::CONST))
+ || ((cvfrom & __attr_type_info::VOLATILE)
+ > (cvto & __attr_type_info::VOLATILE)))
+ goto fail;
+
+ if (*subto == *subfr)
+ new_objptr = objptr;
+ else if (*subto == typeid (void)
+ && dynamic_cast <const __func_type_info *> (subfr) == 0)
+ new_objptr = objptr;
+ else if (const __user_type_info *p
+ = dynamic_cast <const __user_type_info *> (subfr))
+ {
+ /* The 1 skips conversions to private bases. */
+ new_objptr = p->dcast (*subto, 1, objptr);
+ }
+ else if (const __pointer_type_info *pfr
+ = dynamic_cast <const __pointer_type_info *> (subfr))
+ {
+ // Multi-level pointer conversion.
+
+ const __pointer_type_info *pto
+ = dynamic_cast <const __pointer_type_info *> (subto);
+
+ if (! pto)
+ goto fail;
+
+ bool constp = (cvto & __attr_type_info::CONST);
+ for (subto = &pto->type, subfr = &pfr->type; ;
+ subto = &pto->type, subfr = &pfr->type)
+ {
+ if (const __attr_type_info *at
+ = dynamic_cast <const __attr_type_info *> (subfr))
+ {
+ cvfrom = at->attr;
+ subfr = &at->type;
+ }
+ else
+ cvfrom = __attr_type_info::NONE;
+
+ if (const __attr_type_info *at
+ = dynamic_cast <const __attr_type_info *> (subto))
+ {
+ cvto = at->attr;
+ subto = &at->type;
+ }
+ else
+ cvto = __attr_type_info::NONE;
+
+ if (((cvfrom & __attr_type_info::CONST)
+ > (cvto & __attr_type_info::CONST))
+ || ((cvfrom & __attr_type_info::VOLATILE)
+ > (cvto & __attr_type_info::VOLATILE)))
+ goto fail;
+
+ if (! constp
+ && (((cvfrom & __attr_type_info::CONST)
+ < (cvto & __attr_type_info::CONST))
+ || ((cvfrom & __attr_type_info::VOLATILE)
+ < (cvto & __attr_type_info::VOLATILE))))
+ goto fail;
+
+ if (*subto == *subfr)
+ {
+ new_objptr = objptr;
+ break;
+ }
+
+ pto = dynamic_cast <const __pointer_type_info *> (subto);
+ pfr = dynamic_cast <const __pointer_type_info *> (subfr);
+ if (! pto || ! pfr)
+ goto fail;
+
+ if (! (cvto & __attr_type_info::CONST))
+ constp = false;
+ }
+ }
+ }
+ fail:
+
+#if 0
+ if (new_objptr)
+ printf ("It converts, delta is %d\n", new_objptr-objptr);
+#endif
+ return new_objptr;
+}
+
+/* Called from __cp_pop_exception. Is P the type_info node for a pointer
+ of some kind? */
+
+bool
+__is_pointer (void *p)
+{
+ const type_info *t = reinterpret_cast <const type_info *>(p);
+ const __pointer_type_info *pt =
+ dynamic_cast <const __pointer_type_info *> (t);
+ return pt != 0;
+}
+
+extern "C" void
+__rtti_ptr (void *addr, const char *n, const type_info *ti)
+{ new (addr) __pointer_type_info (n, *ti); }
+
+extern "C" void
+__rtti_attr (void *addr, const char *n, int attrval, const type_info *ti)
+{
+ new (addr) __attr_type_info
+ (n, static_cast <__attr_type_info::cv> (attrval), *ti);
+}
+
+extern "C" void
+__rtti_func (void *addr, const char *name)
+{ new (addr) __func_type_info (name); }
+
+extern "C" void
+__rtti_ptmf (void *addr, const char *name)
+{ new (addr) __ptmf_type_info (name); }
+
+extern "C" void
+__rtti_ptmd (void *addr, const char *name)
+{ new (addr) __ptmd_type_info (name); }
+
+extern "C" void
+__rtti_array (void *addr, const char *name)
+{ new (addr) __array_type_info (name); }
+
+extern "C" void *
+__dynamic_cast (const type_info& (*from)(void), const type_info& (*to)(void),
+ int require_public, void *address,
+ const type_info & (*sub)(void), void *subptr)
+{
+ return static_cast <const __user_type_info &> (from ()).dcast
+ (to (), require_public, address, &(sub ()), subptr);
+}
+
+// type_info nodes and functions for the builtin types. The mangling here
+// must match the mangling in gcc/cp/rtti.c.
+
+#define BUILTIN(mangled) \
+unsigned char __ti##mangled [sizeof (__builtin_type_info)] \
+ __attribute__ ((aligned (__alignof__ (void *)))); \
+extern "C" const type_info &__tf##mangled (void) { \
+ if ((*(void **) __ti##mangled) == 0) \
+ new (__ti##mangled) __builtin_type_info (#mangled); \
+ return *(type_info *)__ti##mangled; \
+}
+
+BUILTIN (v); BUILTIN (x); BUILTIN (l); BUILTIN (i); BUILTIN (s); BUILTIN (b);
+BUILTIN (c); BUILTIN (w); BUILTIN (r); BUILTIN (d); BUILTIN (f);
+BUILTIN (Ui); BUILTIN (Ul); BUILTIN (Ux); BUILTIN (Us); BUILTIN (Uc);
diff --git a/gnu/usr.bin/gcc/ginclude/ppc-asm.h b/gnu/usr.bin/gcc/ginclude/ppc-asm.h
new file mode 100644
index 00000000000..4512d94352a
--- /dev/null
+++ b/gnu/usr.bin/gcc/ginclude/ppc-asm.h
@@ -0,0 +1,170 @@
+/* PowerPC asm definitions for GNU C. */
+/* Under winnt, 1) gas supports the following as names and 2) in particular
+ defining "toc" breaks the FUNC_START macro as ".toc" becomes ".2" */
+
+#if !defined(__WINNT__)
+#define r0 0
+#define sp 1
+#define toc 2
+#define r3 3
+#define r4 4
+#define r5 5
+#define r6 6
+#define r7 7
+#define r8 8
+#define r9 9
+#define r10 10
+#define r11 11
+#define r12 12
+#define r13 13
+#define r14 14
+#define r15 15
+#define r16 16
+#define r17 17
+#define r18 18
+#define r19 19
+#define r20 20
+#define r21 21
+#define r22 22
+#define r23 23
+#define r24 24
+#define r25 25
+#define r26 26
+#define r27 27
+#define r28 28
+#define r29 29
+#define r30 30
+#define r31 31
+
+#define cr0 0
+#define cr1 1
+#define cr2 2
+#define cr3 3
+#define cr4 4
+#define cr5 5
+#define cr6 6
+#define cr7 7
+
+#define f0 0
+#define f1 1
+#define f2 2
+#define f3 3
+#define f4 4
+#define f5 5
+#define f6 6
+#define f7 7
+#define f8 8
+#define f9 9
+#define f10 10
+#define f11 11
+#define f12 12
+#define f13 13
+#define f14 14
+#define f15 15
+#define f16 16
+#define f17 17
+#define f18 18
+#define f19 19
+#define f20 20
+#define f21 21
+#define f22 22
+#define f23 23
+#define f24 24
+#define f25 25
+#define f26 26
+#define f27 27
+#define f28 28
+#define f29 29
+#define f30 30
+#define f31 31
+#endif
+
+/*
+ * Macros to glue together two tokens.
+ */
+
+#ifdef __STDC__
+#define XGLUE(a,b) a##b
+#else
+#define XGLUE(a,b) a/**/b
+#endif
+
+#define GLUE(a,b) XGLUE(a,b)
+
+/*
+ * Macros to begin and end a function written in assembler. If -mcall-aixdesc
+ * or -mcall-nt, create a function descriptor with the given name, and create
+ * the real function with one or two leading periods respectively.
+ */
+
+#ifdef _RELOCATABLE
+#define DESC_SECTION ".got2"
+#else
+#define DESC_SECTION ".got1"
+#endif
+
+#if defined(_CALL_AIXDESC)
+#define FUNC_NAME(name) GLUE(.,name)
+#define FUNC_START(name) \
+ .section DESC_SECTION,"aw"; \
+name: \
+ .long GLUE(.,name); \
+ .long _GLOBAL_OFFSET_TABLE_; \
+ .long 0; \
+ .previous; \
+ .type GLUE(.,name),@function; \
+ .globl name; \
+ .globl GLUE(.,name); \
+GLUE(.,name):
+
+#define FUNC_END(name) \
+GLUE(.L,name): \
+ .size GLUE(.,name),GLUE(.L,name)-GLUE(.,name)
+
+#elif defined(__WINNT__)
+#define FUNC_NAME(name) GLUE(..,name)
+#define FUNC_START(name) \
+ .pdata; \
+ .align 2; \
+ .ualong GLUE(..,name),GLUE(name,.e),0,0,GLUE(..,name); \
+ .reldata; \
+name: \
+ .ualong GLUE(..,name),.toc; \
+ .section .text; \
+ .globl name; \
+ .globl GLUE(..,name); \
+GLUE(..,name):
+
+#define FUNC_END(name) \
+GLUE(name,.e): ; \
+GLUE(FE_MOT_RESVD..,name):
+
+#elif defined(_CALL_NT)
+#define FUNC_NAME(name) GLUE(..,name)
+#define FUNC_START(name) \
+ .section DESC_SECTION,"aw"; \
+name: \
+ .long GLUE(..,name); \
+ .long _GLOBAL_OFFSET_TABLE_; \
+ .previous; \
+ .type GLUE(..,name),@function; \
+ .globl name; \
+ .globl GLUE(..,name); \
+GLUE(..,name):
+
+#define FUNC_END(name) \
+GLUE(.L,name): \
+ .size GLUE(..,name),GLUE(.L,name)-GLUE(..,name)
+
+#else
+#define FUNC_NAME(name) name
+#define FUNC_START(name) \
+ .type name,@function; \
+ .globl name; \
+name:
+
+#define FUNC_END(name) \
+GLUE(.L,name): \
+ .size name,GLUE(.L,name)-name
+#endif
+
diff --git a/gnu/usr.bin/gcc/ginclude/va-arc.h b/gnu/usr.bin/gcc/ginclude/va-arc.h
new file mode 100644
index 00000000000..a718ad6245d
--- /dev/null
+++ b/gnu/usr.bin/gcc/ginclude/va-arc.h
@@ -0,0 +1,111 @@
+/* stdarg/varargs support for the ARC */
+
+/* Define __gnuc_va_list. */
+
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+typedef void * __gnuc_va_list;
+#endif /* not __GNUC_VA_LIST */
+
+/* If this is for internal libc use, don't define anything but
+ __gnuc_va_list. */
+#if defined (_STDARG_H) || defined (_VARARGS_H)
+
+/* In GCC version 2, we want an ellipsis at the end of the declaration
+ of the argument list. GCC version 1 can't parse it. */
+
+#if __GNUC__ > 1
+#define __va_ellipsis ...
+#else
+#define __va_ellipsis
+#endif
+
+/* See arc_setup_incoming_varargs for reasons for the oddity in va_start. */
+#ifdef _STDARG_H
+#define va_start(AP, LASTARG) \
+(AP = (__gnuc_va_list) ((int *) __builtin_next_arg (LASTARG) \
+ + (__builtin_args_info (0) < 8 \
+ ? (__builtin_args_info (0) & 1) \
+ : 0)))
+#else
+#define va_alist __builtin_va_alist
+#define va_dcl int __builtin_va_alist; __va_ellipsis
+#define va_start(AP) \
+(AP = (__gnuc_va_list) ((int *) &__builtin_va_alist \
+ + (__builtin_args_info (0) < 8 \
+ ? (__builtin_args_info (0) & 1) \
+ : 0)))
+#endif
+
+#ifndef va_end
+void va_end (__gnuc_va_list); /* Defined in libgcc.a */
+
+/* Values returned by __builtin_classify_type. */
+
+enum __va_type_classes {
+ __no_type_class = -1,
+ __void_type_class,
+ __integer_type_class,
+ __char_type_class,
+ __enumeral_type_class,
+ __boolean_type_class,
+ __pointer_type_class,
+ __reference_type_class,
+ __offset_type_class,
+ __real_type_class,
+ __complex_type_class,
+ __function_type_class,
+ __method_type_class,
+ __record_type_class,
+ __union_type_class,
+ __array_type_class,
+ __string_type_class,
+ __set_type_class,
+ __file_type_class,
+ __lang_type_class
+};
+
+#endif
+#define va_end(AP) ((void)0)
+
+/* Avoid errors if compiling GCC v2 with GCC v1. */
+#if __GNUC__ == 1
+#define __extension__
+#endif
+
+/* All aggregates are passed by reference. All scalar types larger than 8
+ bytes are passed by reference. */
+/* We cast to void * and then to TYPE * because this avoids
+ a warning about increasing the alignment requirement.
+ The casts to char * avoid warnings about invalid pointer arithmetic. */
+
+#define __va_rounded_size(TYPE) \
+ (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
+
+#ifdef __big_endian__
+#define va_arg(AP,TYPE) \
+__extension__ \
+(*({((__builtin_classify_type (*(TYPE*) 0) >= __record_type_class \
+ || __va_rounded_size (TYPE) > 8) \
+ ? ((AP) = (char *)(AP) + __va_rounded_size (TYPE *), \
+ *(TYPE **) (void *) ((char *)(AP) - __va_rounded_size (TYPE *))) \
+ : ((TYPE *) (void *) \
+ (AP = (void *) ((__alignof__ (TYPE) > 4 \
+ ? ((int) AP + 8 - 1) & -8 \
+ : (int) AP) \
+ + __va_rounded_size (TYPE))) - 1));}))
+#else
+#define va_arg(AP,TYPE) \
+__extension__ \
+(*({((__builtin_classify_type (*(TYPE*) 0) >= __record_type_class \
+ || __va_rounded_size (TYPE) > 8) \
+ ? ((AP) = (char *)(AP) + __va_rounded_size (TYPE *), \
+ *(TYPE **) (void *) ((char *)(AP) - __va_rounded_size (TYPE *))) \
+ : ((AP = (void *) ((__alignof__ (TYPE) > 4 \
+ ? ((int) AP + 8 - 1) & -8 \
+ : (int) AP) \
+ + __va_rounded_size (TYPE))), \
+ (TYPE *) (void *) (AP - __va_rounded_size (TYPE))));}))
+#endif
+
+#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
diff --git a/gnu/usr.bin/gcc/ginclude/va-m32r.h b/gnu/usr.bin/gcc/ginclude/va-m32r.h
new file mode 100644
index 00000000000..4ef0ad8267a
--- /dev/null
+++ b/gnu/usr.bin/gcc/ginclude/va-m32r.h
@@ -0,0 +1,86 @@
+/* GNU C stdarg/varargs support for the M32R */
+
+/* Define __gnuc_va_list. */
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+typedef void *__gnuc_va_list;
+#endif /* not __GNUC_VA_LIST */
+
+/* If this is for internal libc use, don't define anything but
+ __gnuc_va_list. */
+#if defined (_STDARG_H) || defined (_VARARGS_H)
+
+/* Common code for va_start for both varargs and stdarg. */
+
+#define __va_rounded_size(TYPE) \
+ (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
+
+#ifdef _STDARG_H /* stdarg.h support */
+
+/* Calling __builtin_next_arg gives the proper error message if LASTARG is
+ not indeed the last argument. */
+#define va_start(AP, LASTARG) \
+ (AP = ((__gnuc_va_list) __builtin_next_arg (LASTARG)))
+
+#else /* varargs.h support */
+
+#define va_alist __builtin_va_alist
+/* The ... causes current_function_varargs to be set in cc1. */
+#define va_dcl int __builtin_va_alist; ...
+#define va_start(AP) AP=(char *) &__builtin_va_alist
+
+#endif /* _STDARG_H */
+
+/* Nothing needs to be done to end varargs/stdarg processing */
+#define va_end(AP) ((void) 0)
+
+/* Values returned by __builtin_classify_type. */
+enum __type_class
+{
+ __no_type_class = -1,
+ __void_type_class,
+ __integer_type_class,
+ __char_type_class,
+ __enumeral_type_class,
+ __boolean_type_class,
+ __pointer_type_class,
+ __reference_type_class,
+ __offset_type_class,
+ __real_type_class,
+ __complex_type_class,
+ __function_type_class,
+ __method_type_class,
+ __record_type_class,
+ __union_type_class,
+ __array_type_class,
+ __string_type_class,
+ __set_type_class,
+ __file_type_class,
+ __lang_type_class
+};
+
+/* Return whether a type is passed by reference. */
+#define __va_by_reference_p(TYPE) (sizeof (TYPE) > 8)
+
+#define va_arg(AP,TYPE) \
+__extension__ (*({ \
+ register TYPE *__ptr; \
+ \
+ if (__va_by_reference_p (TYPE)) \
+ { \
+ __ptr = *(TYPE **)(void *) (AP); \
+ (AP) = (__gnuc_va_list) ((char *) (AP) + sizeof (void *)); \
+ } \
+ else \
+ { \
+ __ptr = (TYPE *)(void *) \
+ ((char *) (AP) + (sizeof (TYPE) < __va_rounded_size (char) \
+ ? __va_rounded_size (TYPE) - sizeof (TYPE) \
+ : 0)); \
+ (AP) = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)); \
+ } \
+ \
+ __ptr; \
+}))
+
+#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
diff --git a/gnu/usr.bin/gcc/ginclude/va-mn10200.h b/gnu/usr.bin/gcc/ginclude/va-mn10200.h
new file mode 100644
index 00000000000..b458b56e0be
--- /dev/null
+++ b/gnu/usr.bin/gcc/ginclude/va-mn10200.h
@@ -0,0 +1,37 @@
+/* CYGNUS LOCAL entire file/law */
+/* Define __gnuc_va_list. */
+
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+typedef void *__gnuc_va_list;
+#endif /* not __GNUC_VA_LIST */
+
+/* If this is for internal libc use, don't define anything but
+ __gnuc_va_list. */
+#if defined (_STDARG_H) || defined (_VARARGS_H)
+#define __gnuc_va_start(AP) (AP = (__gnuc_va_list)__builtin_saveregs())
+#define __va_ellipsis ...
+
+#ifdef _STDARG_H
+#define va_start(AP, LASTARG) \
+ (AP = ((__gnuc_va_list) __builtin_next_arg (LASTARG)))
+#else
+#define va_alist __builtin_va_alist
+#define va_dcl int __builtin_va_alist; __va_ellipsis
+#define va_start(AP) AP=(char *) &__builtin_va_alist
+#endif
+
+/* Now stuff common to both varargs & stdarg implementations. */
+#define __va_rounded_size(TYPE) \
+ (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
+#undef va_end
+void va_end (__gnuc_va_list);
+#define va_end(AP) ((void)0)
+#define va_arg(AP, TYPE) \
+ (sizeof (TYPE) > 8 \
+ ? (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (char *)),\
+ **((TYPE **) (void *) ((char *) (AP) - __va_rounded_size (char *))))\
+ : (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \
+ *((TYPE *) (void *) ((char *) (AP) - __va_rounded_size (TYPE)))))
+#endif
+/* END CYGNUS LOCAL */
diff --git a/gnu/usr.bin/gcc/ginclude/va-mn10300.h b/gnu/usr.bin/gcc/ginclude/va-mn10300.h
new file mode 100644
index 00000000000..e156ccf5939
--- /dev/null
+++ b/gnu/usr.bin/gcc/ginclude/va-mn10300.h
@@ -0,0 +1,35 @@
+/* Define __gnuc_va_list. */
+
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+typedef void *__gnuc_va_list;
+#endif /* not __GNUC_VA_LIST */
+
+/* If this is for internal libc use, don't define anything but
+ __gnuc_va_list. */
+#if defined (_STDARG_H) || defined (_VARARGS_H)
+#define __gnuc_va_start(AP) (AP = (__gnuc_va_list)__builtin_saveregs())
+#define __va_ellipsis ...
+
+#ifdef _STDARG_H
+#define va_start(AP, LASTARG) \
+ (__builtin_next_arg (LASTARG), __gnuc_va_start (AP))
+#else
+#define va_alist __builtin_va_alist
+#define va_dcl int __builtin_va_alist; __va_ellipsis
+#define va_start(AP) AP=(char *) &__builtin_va_alist
+#endif
+
+/* Now stuff common to both varargs & stdarg implementations. */
+#define __va_rounded_size(TYPE) \
+ (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
+#undef va_end
+void va_end (__gnuc_va_list);
+#define va_end(AP) ((void)0)
+#define va_arg(AP, TYPE) \
+ (sizeof (TYPE) > 8 \
+ ? (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (char *)),\
+ **((TYPE **) (void *) ((char *) (AP) - __va_rounded_size (char *))))\
+ : (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \
+ *((TYPE *) (void *) ((char *) (AP) - __va_rounded_size (TYPE)))))
+#endif
diff --git a/gnu/usr.bin/gcc/ginclude/va-sh.h b/gnu/usr.bin/gcc/ginclude/va-sh.h
new file mode 100644
index 00000000000..f1671c7b0b6
--- /dev/null
+++ b/gnu/usr.bin/gcc/ginclude/va-sh.h
@@ -0,0 +1,199 @@
+/* This is just like the default gvarargs.h
+ except for differences described below. */
+
+/* Define __gnuc_va_list. */
+
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+
+#ifdef __SH3E__
+
+typedef long __va_greg;
+typedef double __va_freg;
+
+typedef struct {
+ __va_greg * __va_next_o; /* next available register */
+ __va_greg * __va_next_o_limit; /* past last available register */
+ __va_freg * __va_next_fp; /* next available fp register */
+ __va_freg * __va_next_fp_limit; /* last available fp register */
+ __va_greg * __va_next_stack; /* next extended word on stack */
+} __gnuc_va_list;
+
+#else /* ! SH3E */
+
+typedef void *__gnuc_va_list;
+
+#endif /* ! SH3E */
+
+#endif /* __GNUC_VA_LIST */
+
+/* If this is for internal libc use, don't define anything but
+ __gnuc_va_list. */
+#if defined (_STDARG_H) || defined (_VARARGS_H)
+
+#ifdef _STDARG_H
+
+#ifdef __SH3E__
+
+#define va_start(AP, LASTARG) \
+__extension__ \
+ ({ \
+ AP.__va_next_fp = (__va_freg *) __builtin_saveregs (); \
+ AP.__va_next_fp_limit = (AP.__va_next_fp + \
+ (__builtin_args_info (1) < 8 ? 8 - __builtin_args_info (1) : 0)); \
+ AP.__va_next_o = (__va_greg *) AP.__va_next_fp_limit; \
+ AP.__va_next_o_limit = (AP.__va_next_o + \
+ (__builtin_args_info (0) < 4 ? 4 - __builtin_args_info (0) : 0)); \
+ AP.__va_next_stack = (__va_greg *) __builtin_next_arg (LASTARG); \
+ })
+
+#else /* ! SH3E */
+
+#define va_start(AP, LASTARG) \
+ (AP = ((__gnuc_va_list) __builtin_next_arg (LASTARG)))
+
+#endif /* ! SH3E */
+
+#else /* _VARARGS_H */
+
+#define va_alist __builtin_va_alist
+#define va_dcl int __builtin_va_alist;...
+
+#ifdef __SH3E__
+
+#define va_start(AP) \
+__extension__ \
+ ({ \
+ AP.__va_next_fp = (__va_freg *) __builtin_saveregs (); \
+ AP.__va_next_fp_limit = (AP.__va_next_fp + \
+ (__builtin_args_info (1) < 8 ? 8 - __builtin_args_info (1) : 0)); \
+ AP.__va_next_o = (__va_greg *) AP.__va_next_fp_limit; \
+ AP.__va_next_o_limit = (AP.__va_next_o + \
+ (__builtin_args_info (0) < 4 ? 4 - __builtin_args_info (0) : 0)); \
+ AP.__va_next_stack = (__va_greg *) __builtin_next_arg (__builtin_va_alist) \
+ - (__builtin_args_info (0) >= 4 || __builtin_args_info (1) >= 8 ? 1 : 0); \
+ })
+
+#else /* ! SH3E */
+
+#define va_start(AP) AP=(char *) &__builtin_va_alist
+
+#endif /* ! SH3E */
+
+#endif /* _STDARG */
+
+#ifndef va_end
+void va_end (__gnuc_va_list); /* Defined in libgcc.a */
+
+/* Values returned by __builtin_classify_type. */
+
+enum __va_type_classes {
+ __no_type_class = -1,
+ __void_type_class,
+ __integer_type_class,
+ __char_type_class,
+ __enumeral_type_class,
+ __boolean_type_class,
+ __pointer_type_class,
+ __reference_type_class,
+ __offset_type_class,
+ __real_type_class,
+ __complex_type_class,
+ __function_type_class,
+ __method_type_class,
+ __record_type_class,
+ __union_type_class,
+ __array_type_class,
+ __string_type_class,
+ __set_type_class,
+ __file_type_class,
+ __lang_type_class
+};
+
+#endif
+#define va_end(pvar) ((void)0)
+
+#ifdef __LITTLE_ENDIAN__
+#define __LITTLE_ENDIAN_P 1
+#else
+#define __LITTLE_ENDIAN_P 0
+#endif
+
+#define __SCALAR_TYPE(TYPE) \
+ ((TYPE) == __integer_type_class \
+ || (TYPE) == __char_type_class \
+ || (TYPE) == __enumeral_type_class)
+
+/* RECORD_TYPE args passed using the C calling convention are
+ passed by invisible reference. ??? RECORD_TYPE args passed
+ in the stack are made to be word-aligned; for an aggregate that is
+ not word-aligned, we advance the pointer to the first non-reg slot. */
+
+ /* When this is a smaller-than-int integer, using
+ auto-increment in the promoted (SImode) is fastest;
+ however, there is no way to express that is C. Therefore,
+ we use an asm.
+ We want the MEM_IN_STRUCT_P bit set in the emitted RTL, therefore we
+ use unions even when it would otherwise be unnecessary. */
+
+#define __va_arg_sh1(AP, TYPE) __extension__ \
+__extension__ \
+({(sizeof (TYPE) == 1 \
+ ? ({union {TYPE t; char c;} __t; \
+ asm("" \
+ : "=r" (__t.c) \
+ : "0" ((((union { int i, j; } *) (AP))++)->i)); \
+ __t.t;}) \
+ : sizeof (TYPE) == 2 \
+ ? ({union {TYPE t; short s;} __t; \
+ asm("" \
+ : "=r" (__t.s) \
+ : "0" ((((union { int i, j; } *) (AP))++)->i)); \
+ __t.t;}) \
+ : sizeof (TYPE) >= 4 || __LITTLE_ENDIAN_P \
+ ? (((union { TYPE t; int i;} *) (AP))++)->t \
+ : ((union {TYPE t;TYPE u;}*) ((char *)++(int *)(AP) - sizeof (TYPE)))->t);})
+
+#ifdef __SH3E__
+
+#define __PASS_AS_FLOAT(TYPE_CLASS,SIZE) \
+ (TYPE_CLASS == __real_type_class && SIZE == 4)
+
+#define va_arg(pvar,TYPE) \
+__extension__ \
+({int __type = __builtin_classify_type (* (TYPE *) 0); \
+ void * __result_p; \
+ if (__PASS_AS_FLOAT (__type, sizeof(TYPE))) \
+ { \
+ if (pvar.__va_next_fp < pvar.__va_next_fp_limit) \
+ { \
+ __result_p = &pvar.__va_next_fp; \
+ } \
+ else \
+ __result_p = &pvar.__va_next_stack; \
+ } \
+ else \
+ { \
+ if (pvar.__va_next_o + ((sizeof (TYPE) + 3) / 4) \
+ <= pvar.__va_next_o_limit) \
+ __result_p = &pvar.__va_next_o; \
+ else \
+ { \
+ if (sizeof (TYPE) > 4) \
+ pvar.__va_next_o = pvar.__va_next_o_limit; \
+ \
+ __result_p = &pvar.__va_next_stack; \
+ } \
+ } \
+ __va_arg_sh1(*(void **)__result_p, TYPE);})
+
+#else /* ! SH3E */
+
+#define va_arg(AP, TYPE) __va_arg_sh1((AP), TYPE)
+
+#endif /* SH3E */
+
+/* Copy __gnuc_va_list into another variable of this type. */
+#define __va_copy(dest, src) (dest) = (src)
+
+#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
diff --git a/gnu/usr.bin/gcc/ginclude/va-v850.h b/gnu/usr.bin/gcc/ginclude/va-v850.h
new file mode 100644
index 00000000000..96da6d5a3de
--- /dev/null
+++ b/gnu/usr.bin/gcc/ginclude/va-v850.h
@@ -0,0 +1,34 @@
+/* Define __gnuc_va_list. */
+
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+typedef void *__gnuc_va_list;
+#endif /* not __GNUC_VA_LIST */
+
+/* If this is for internal libc use, don't define anything but
+ __gnuc_va_list. */
+#if defined (_STDARG_H) || defined (_VARARGS_H)
+
+#ifdef _STDARG_H
+#define va_start(AP, LASTARG) \
+ (AP = ((__gnuc_va_list) __builtin_next_arg (LASTARG)))
+#else
+#define __va_ellipsis ...
+#define va_alist __builtin_va_alist
+#define va_dcl int __builtin_va_alist; __va_ellipsis
+#define va_start(AP) AP=(char *) &__builtin_va_alist
+#endif
+
+/* Now stuff common to both varargs & stdarg implementations. */
+#define __va_rounded_size(TYPE) \
+ (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
+#undef va_end
+void va_end (__gnuc_va_list);
+#define va_end(AP) ((void)0)
+#define va_arg(AP, TYPE) \
+ (sizeof (TYPE) > 8 \
+ ? (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (char *)),\
+ **((TYPE **) (void *) ((char *) (AP) - __va_rounded_size (char *))))\
+ : (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \
+ *((TYPE *) (void *) ((char *) (AP) - __va_rounded_size (TYPE)))))
+#endif
diff --git a/gnu/usr.bin/gcc/objc/Make-lang.in b/gnu/usr.bin/gcc/objc/Make-lang.in
new file mode 100644
index 00000000000..1170d5a1439
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/Make-lang.in
@@ -0,0 +1,308 @@
+# Top level makefile fragment for GNU Objective-C
+# Copyright (C) 1997 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 provides the language dependent support in the main Makefile.
+# Each language makefile fragment must provide the following targets:
+#
+# foo.all.build, foo.all.cross, foo.start.encap, foo.rest.encap,
+# foo.info, foo.dvi,
+# foo.install-normal, foo.install-common, foo.install-info, foo.install-man,
+# foo.uninstall, foo.distdir,
+# foo.mostlyclean, foo.clean, foo.distclean, foo.extraclean,
+# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4
+#
+# where `foo' is the name of the language.
+#
+# It should also provide rules for:
+#
+# - making any compiler driver (eg: g++)
+# - the compiler proper (eg: cc1plus)
+# - define the names for selecting the language in LANGUAGES.
+#
+# Extra flags to pass to recursive makes.
+OBJC_FLAGS_TO_PASS = \
+ "OBJC_FOR_BUILD=$(OBJC_FOR_BUILD)" \
+ "OBJCFLAGS=$(OBJCFLAGS)" \
+ "OBJC_FOR_TARGET=$(OBJC_FOR_TARGET)" \
+
+# Actual names to use when installing a native compiler.
+#OBJC_INSTALL_NAME = `t='$(program_transform_name)'; echo c++ | sed $$t`
+
+# Actual names to use when installing a cross-compiler.
+#OBJC_CROSS_NAME = `t='$(program_transform_cross_name)'; echo c++ | sed $$t`
+
+#
+# Define the names for selecting Objective-C in LANGUAGES.
+OBJC objc: cc1obj objc-runtime
+OBJECTIVE-C objective-c: cc1obj objc-runtime
+
+# Tell GNU make to ignore these if they exist.
+.PHONY: objective-c objc ObjC
+
+# The Objective C thread file
+OBJC_THREAD_FILE=thr-$(GCC_THREAD_FILE)
+
+# Language-specific object files for Objective C.
+OBJC_OBJS = objc-parse.o objc-act.o $(C_AND_OBJC_OBJS)
+
+cc1obj: $(P) $(OBJC_OBJS) $(OBJS) $(BC_OBJS) $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(OBJC_OBJS) $(OBJS) \
+ $(BC_OBJS) $(LIBS)
+
+# Objective C language specific files.
+
+objc-parse.o : $(srcdir)/objc/objc-parse.c \
+ $(CONFIG_H) $(TREE_H) \
+ $(srcdir)/c-lex.h $(srcdir)/c-tree.h $(srcdir)/input.h \
+ $(srcdir)/flags.h $(srcdir)/output.h $(srcdir)/objc/objc-act.h
+ $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \
+ -c $(srcdir)/objc/objc-parse.c
+
+$(srcdir)/objc/objc-parse.c : $(srcdir)/objc/objc-parse.y
+ cd $(srcdir)/objc; \
+ $(BISON) $(BISONFLAGS) objc-parse.y -o objc-parse.c
+
+$(srcdir)/objc/objc-parse.y: $(srcdir)/c-parse.in
+ echo '/*WARNING: This file is automatically generated!*/' >tmp-objc-prs.y
+ sed -e "/^ifc$$/,/^end ifc$$/d" \
+ -e "/^ifobjc$$/d" -e "/^end ifobjc$$/d" \
+ $(srcdir)/c-parse.in >>tmp-objc-prs.y
+ $(srcdir)/move-if-change tmp-objc-prs.y $(srcdir)/objc/objc-parse.y
+
+objc-act.o : $(srcdir)/objc/objc-act.c \
+ $(CONFIG_H) $(TREE_H) $(RTL_H) \
+ $(srcdir)/c-tree.h $(srcdir)/c-lex.h \
+ $(srcdir)/flags.h $(srcdir)/objc/objc-act.h $(srcdir)/input.h \
+ $(srcdir)/function.h $(srcdir)/output.h $(srcdir)/c-parse.h
+ $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \
+ -c $(srcdir)/objc/objc-act.c
+
+objc-runtime: objc-headers libobjc.a
+
+# copy objc header files into build directory
+objc-headers: stmp-fixinc
+ if [ -d include ]; then true; else mkdir include; fi
+ cd objc; \
+ if [ -f Makefile ]; then \
+ $(MAKE) copy-headers \
+ tooldir=$(tooldir) \
+ AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" \
+ GCC_FOR_TARGET="../xgcc -B../" \
+ GCC_CFLAGS="$(GCC_CFLAGS)" incinstalldir=../include; \
+ fi
+ touch objc-headers
+
+# Objective C runtime library specific files.
+
+OBJC_O = objc/hash.o objc/sarray.o \
+ objc/class.o objc/sendmsg.o \
+ objc/init.o objc/archive.o \
+ objc/encoding.o objc/selector.o \
+ objc/objects.o objc/misc.o \
+ objc/NXConstStr.o objc/Object.o \
+ objc/Protocol.o objc/nil_method.o \
+ objc/thr.o objc/linking.o \
+ objc/$(OBJC_THREAD_FILE).o
+
+objc/hash.o: $(srcdir)/objc/hash.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -c $(srcdir)/objc/hash.c -o $@
+objc/sarray.o: $(srcdir)/objc/sarray.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -c $(srcdir)/objc/sarray.c -o $@
+objc/class.o: $(srcdir)/objc/class.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -c $(srcdir)/objc/class.c -o $@
+objc/sendmsg.o: $(srcdir)/objc/sendmsg.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) -Iobjc \
+ -c $(srcdir)/objc/sendmsg.c -o $@
+objc/init.o: $(srcdir)/objc/init.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -c $(srcdir)/objc/init.c -o $@
+objc/archive.o: $(srcdir)/objc/archive.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -c $(srcdir)/objc/archive.c -o $@
+objc/encoding.o: $(srcdir)/objc/encoding.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -c $(srcdir)/objc/encoding.c -o $@
+objc/selector.o: $(srcdir)/objc/selector.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -c $(srcdir)/objc/selector.c -o $@
+objc/objects.o: $(srcdir)/objc/objects.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -c $(srcdir)/objc/objects.c -o $@
+objc/misc.o: $(srcdir)/objc/misc.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -c $(srcdir)/objc/misc.c -o $@
+objc/NXConstStr.o: $(srcdir)/objc/NXConstStr.m $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -fgnu-runtime -c $(srcdir)/objc/NXConstStr.m -o $@
+objc/Object.o: $(srcdir)/objc/Object.m $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -fgnu-runtime -c $(srcdir)/objc/Object.m -o $@
+objc/Protocol.o: $(srcdir)/objc/Protocol.m $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -fgnu-runtime -c $(srcdir)/objc/Protocol.m -o $@
+objc/thr.o: $(srcdir)/objc/thr.h $(srcdir)/objc/thr.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -c $(srcdir)/objc/thr.c -o $@
+objc/$(OBJC_THREAD_FILE).o: $(srcdir)/objc/$(OBJC_THREAD_FILE).c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -c $(srcdir)/objc/$(OBJC_THREAD_FILE).c -o $@
+objc/nil_method.o: $(srcdir)/objc/nil_method.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -c $(srcdir)/objc/nil_method.c -o $@
+objc/linking.o: $(srcdir)/objc/linking.m $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -fgnu-runtime -c $(srcdir)/objc/linking.m -o $@
+
+objc/libobjc_entry.o: $(srcdir)/objc/libobjc_entry.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ -c $(srcdir)/objc/libobjc_entry.c -o $@
+
+# Build the Objective C runtime library.
+libobjc.a: cc1obj specs stmp-int-hdrs libgcc2.ready \
+ $(USE_COLLECT2) $(EXTRA_PARTS) objc/runtime-info.h $(OBJC_O)
+ -rm -f libobjc.a
+ $(AR) $(AR_FLAGS) libobjc.a $(OBJC_O)
+ -if $(RANLIB_TEST) ; then $(RANLIB) libobjc.a; else true; fi
+
+libobjc_s.a: libobjc.a
+ mv libobjc.a libobjc_s.a
+
+# Create a relocatable DLL
+libobjc.dll: libobjc_s.a objc/libobjc_entry.o
+ $(GCC_FOR_TARGET) -mdll -Wl,--base-file -Wl,libobjc.base \
+ -o libobjc.dll libobjc_s.a \
+ objc/libobjc_entry.o -lkernel32
+ $(DLLTOOL) --dllname libobjc.dll --def $(srcdir)/objc/libobjc.def \
+ --base-file libobjc.base --output-exp libobjc.exp
+ $(GCC_FOR_TARGET) -mdll -Wl,--base-file libobjc.base libobjc.exp \
+ -o libobjc.dll libobjc_s.a \
+ objc/libobjc_entry.o -lkernel32
+ $(DLLTOOL) --dllname libobjc.dll --def $(srcdir)/objc/libobjc.def \
+ --base-file libobjc.base --output-exp libobjc.exp
+ $(GCC_FOR_TARGET) libobjc.exp -mdll \
+ -o libobjc.dll libobjc_s.a \
+ objc/libobjc_entry.o -lkernel32
+ $(DLLTOOL) --dllname libobjc.dll --def $(srcdir)/objc/libobjc.def \
+ --output-lib libobjc.a
+
+# Platform generated information needed by ObjC runtime
+objc/runtime-info.h: cc1obj
+ echo "" > emptyfile
+ echo "/* This file is automatically generated */" >$@
+ ./cc1obj -print-objc-runtime-info emptyfile >>$@
+
+#
+# Build hooks:
+
+objc.all.build:
+objc.all.cross:
+objc.start.encap:
+objc.rest.encap:
+
+objc.info:
+objc.dvi:
+
+#
+# Install hooks:
+# cc1obj is installed elsewhere as part of $(COMPILERS).
+
+objc.install-normal: installdirs
+ -if [ -f libobjc.a ] ; then \
+ rm -f $(libsubdir)/libobjc.a; \
+ $(INSTALL_DATA) libobjc.a $(libsubdir)/libobjc.a; \
+ if $(RANLIB_TEST) ; then \
+ (cd $(libsubdir); $(RANLIB) libobjc.a); else true; fi; \
+ chmod a-x $(libsubdir)/libobjc.a; \
+ else true; fi
+ -if [ -f libobjc_s.a ] ; then \
+ rm -f $(libsubdir)/libobjc_s.a; \
+ $(INSTALL_DATA) libobjc_s.a $(libsubdir)/libobjc_s.a; \
+ if $(RANLIB_TEST) ; then \
+ (cd $(libsubdir); $(RANLIB) libobjc_s.a); else true; fi; \
+ chmod a-x $(libsubdir)/libobjc_s.a; \
+ else true; fi
+ -if [ -f libobjc.dll ] ; then \
+ rm -f $(bindir)/libobjc.dll; \
+ $(INSTALL_DATA) libobjc.dll $(bindir)/libobjc.dll; \
+ else true; fi
+
+objc.install-common:
+
+objc.install-info:
+
+objc.install-man:
+
+objc.uninstall:
+#
+# Clean hooks:
+# A lot of the ancillary files are deleted by the main makefile.
+# We just have to delete files specific to us.
+objc.mostlyclean:
+ -rm -f tmp-objc-prs.y
+ -rm -f objc/*$(objext) objc/xforward objc/fflags
+ -rm -f objc/runtime-info.h
+ -rm -f libobjc.a libobjc_s.a libobjc.dll
+ -rm -f libobjc.base libobjc.exp
+objc.clean: objc.mostlyclean
+ -rm -rf objc-headers
+objc.distclean:
+ -rm -f objc/Makefile objc/Make-host objc/Make-target
+ -rm -f objc/config.status objc/config.cache
+ -rm -f objc-parse.output
+objc.extraclean:
+objc.maintainer-clean:
+ -rm -f objc/objc-parse.y
+ -rm -f objc/objc-parse.c objc/objc-parse.output
+
+#
+# Stage hooks:
+
+objc.stage1:
+ -mv objc/*$(objext) stage1/objc
+ -mv cc1obj$(exeext) stage1
+ -mv libobjc.a stage1
+objc.stage2:
+ -mv objc/*$(objext) stage2/objc
+ -mv cc1obj$(exeext) stage2
+ -mv libobjc.a stage2
+objc.stage3:
+ -mv objc/*$(objext) stage3/objc
+ -mv cc1obj$(exeext) stage3
+ -mv libobjc.a stage3
+objc.stage4:
+ -mv objc/*$(objext) stage4/objc
+ -mv cc1obj$(exeext) stage4
+ -mv libobjc.a stage4
+
+#
+# Maintenance hooks:
+
+# This target creates the files that can be rebuilt, but go in the
+# distribution anyway. It then copies the files to the distdir directory.
+objc.distdir:
+ mkdir tmp/objc
+ cd objc ; $(MAKE) $(FLAGS_TO_PASS) objc-parse.c
+ cd objc; \
+ for file in *[0-9a-zA-Z+]; do \
+ ln $$file ../tmp/objc >/dev/null 2>&1 || cp $$file ../tmp/objc; \
+ done
diff --git a/gnu/usr.bin/gcc/objc/Makefile.in b/gnu/usr.bin/gcc/objc/Makefile.in
new file mode 100644
index 00000000000..9d521f54cdc
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/Makefile.in
@@ -0,0 +1,91 @@
+# GNU Objective C Runtime Makefile
+# Copyright (C) 1993, 1995, 1996, 1997 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 makefile is run by the parent dir's makefile.
+# thisdir1=`pwd`; \
+# srcdir1=`cd $(srcdir); pwd`; \
+# cd objc; \
+# $(MAKE) $(MAKEFLAGS) -f $$srcdir1/objc/Makefile libobjc.a \
+# srcdir=$$srcdir1 tooldir=$(tooldir) AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" \
+# GCC_FOR_TARGET="$$thisdir1/xgcc -B$$thisdir1/" \
+# GCC_CFLAGS="$(GCC_CFLAGS)" incinstalldir=$$thisdir1/include
+# OBJC_THREAD_FILE="$(OBJC_THREAD_FILE)"
+# Two targets are used by ../Makefile: `all' and `mostlyclean'.
+
+SHELL=/bin/sh
+
+.SUFFIXES: .m
+
+OPTIMIZE= -O
+
+srcdir = .
+VPATH = $(srcdir)
+
+AR = ar
+AR_FLAGS = rc
+
+# Define this as & to perform parallel make on a Sequent.
+# Note that this has some bugs, and it seems currently necessary
+# to compile all the gen* files first by hand to avoid erroneous results.
+P =
+
+# Definition of `all' is here so that new rules inserted by sed
+# do not specify the default target.
+all: all.indirect
+
+# sed inserts variable overrides after the following line.
+####target overrides
+####host overrides
+####cross overrides
+####build overrides
+#
+
+OBJC_H = hash.h objc-list.h sarray.h objc.h objc-api.h \
+ NXConstStr.h Object.h Protocol.h encoding.h typedstream.h thr.h
+
+# Now figure out from those variables how to compile and link.
+all.indirect: Makefile compiler objc-runtime
+
+compiler:
+ cd ..; $(MAKE) cc1obj
+
+objc-runtime:
+ cd ..; $(MAKE) libobjc.a
+
+# copy objc headers to installation include directory
+copy-headers:
+ -rm -fr $(incinstalldir)/objc
+ -mkdir $(incinstalldir)/objc
+ for file in $(OBJC_H); do \
+ realfile=$(srcdir)/$${file}; \
+ cp $${realfile} $(incinstalldir)/objc; \
+ chmod a+r $(incinstalldir)/objc/$${file}; \
+ done
+
+Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure
+ cd ..; $(SHELL) config.status
+
+mostlyclean:
+ -rm -f *.o libobjc.a xforward fflags
+clean: mostlyclean
+distclean: mostlyclean
+extraclean: mostlyclean
+
+# For Sun VPATH.
+
diff --git a/gnu/usr.bin/gcc/objc/README.threads b/gnu/usr.bin/gcc/objc/README.threads
new file mode 100644
index 00000000000..2cafb4ea7cf
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/README.threads
@@ -0,0 +1,50 @@
+==============================================================================
+README - Wed Nov 29 15:16:24 EST 1995
+------------------------------------------------------------------------------
+
+Limited documentation is available in the THREADS file.
+
+This version has been tested on Sun Solaris, SGI Irix, and Windows NT.
+It should also work on any single threaded system.
+
+Thanks go to the following people for help test and debug the library:
+
+ Scott Christley, scottc@ocbi.com
+ Andrew McCallum, mccallum@cs.rochester.edu
+
+galen
+gchunt@cs.rochester.edu
+
+Any questions, bug reports, etc should be directed to:
+
+Scott Christley, scottc@ocbi.com
+
+Please do not bug Galen with email as he no longer supports the code.
+
+==============================================================================
+Changes from prior releases (in revered chronological order):
+------------------------------------------------------------------------------
+
+* Fixed bug in copy part of sarray_realloc. I had an < which should
+ have been <=. (Bug report from Scott).
+
+------------------------------------------------------------------------------
+
+* Support for DEC OSF/1 is definitely broken. My programs always
+ seg-fault when I link with libpthreads.a.
+
+* Thread id's are no longer int's, but are instead of type
+ _objc_thread_t which is typedef'ed from a void *. An invalid thread
+ id is denoted by NULL and not -1 as before.
+
+------------------------------------------------------------------------------
+
+* Renamed thread-winnt.c to thread-win32.c to better reflect support
+ for the API on both Windows NT and Windows 95 platforms.
+ (Who knows, maybe even Win32s :-).
+
+* Fixed bugs in Win32 support as per report from Scott Christley.
+
+* Fixed bug in sarray_get as per report from Scott Christley.
+
+
diff --git a/gnu/usr.bin/gcc/objc/THREADS b/gnu/usr.bin/gcc/objc/THREADS
new file mode 100644
index 00000000000..9dfbbed97af
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/THREADS
@@ -0,0 +1,374 @@
+This file describes in little detail the modifications to the
+Objective-C runtime needed to make it thread safe.
+
+First off, kudos to Galen Hunt who is the author of this great work.
+
+If you have an comments or just want to know where to
+send me money to express your undying gratitude for threading the
+Objective-C runtime you can reach Galen at:
+
+ gchunt@cs.rochester.edu
+
+Any questions, comments, bug reports, etc. should send email either to the
+GCC bug account or to:
+
+ Scott Christley <scottc@net-community.com>
+
+* Sarray Threading:
+
+The most critical component of the Objective-C runtime is the sparse array
+structure (sarray). Sarrays store object selectors and implementations.
+Following in the tradition of the Objective-C runtime, my threading
+support assumes that fast message dispatching is far more important
+than *ANY* and *ALL* other operations. The message dispatching thus
+uses *NO* locks on any kind. In fact, if you look in sarray.h, you
+will notice that the message dispatching has not been modified.
+Instead, I have modified the sarray management functions so that all
+updates to the sarray data structure can be made in parallel will
+message dispatching.
+
+To support concurrent message dispatching, no dynamically allocated
+sarray data structures are freed while more than one thread is
+operational. Sarray data structures that are no longer in use are
+kept in a linked list of garbage and are released whenever the program
+is operating with a single thread. The programmer can also flush the
+garbage list by calling sarray_remove_garbage when the programmer can
+ensure that no message dispatching is taking place concurrently. The
+amount of un-reclaimed sarray garbage should normally be extremely
+small in a real program as sarray structures are freed only when using
+the "poseAs" functionality and early in program initialization, which
+normally occurs while the program is single threaded.
+
+******************************************************************************
+* Static Variables:
+
+The following variables are either statically or globally defined. This list
+does not include variables which are internal to implementation dependent
+versions of thread-*.c.
+
+The following threading designations are used:
+ SAFE : Implicitly thread safe.
+ SINGLE : Must only be used in single thread mode.
+ MUTEX : Protected by single global mutex objc_runtime_mutex.
+ UNUSED : Not used in the runtime.
+
+Variable Name: Usage: Defined: Also used in:
+=========================== ====== ============ =====================
+__objc_class_hash MUTEX class.c
+__objc_class_links_resolved UNUSED class.c runtime.h
+__objc_class_number MUTEX class.c
+__objc_dangling_categories UNUSED init.c
+__objc_module_list MUTEX init.c
+__objc_selector_array MUTEX selector.c
+__objc_selector_hash MUTEX selector.c
+__objc_selector_max_index MUTEX selector.c sendmsg.c runtime.h
+__objc_selector_names MUTEX selector.c
+__objc_thread_exit_status SAFE thread.c
+__objc_uninstalled_dtable MUTEX sendmsg.c selector.c
+_objc_load_callback SAFE init.c objc-api.h
+_objc_lookup_class SAFE class.c objc-api.h
+_objc_object_alloc SINGLE objects.c objc-api.h
+_objc_object_copy SINGLE objects.c objc-api.h
+_objc_object_dispose SINGLE objects.c objc-api.h
+frwd_sel SAFE2 sendmsg.c
+idxsize MUTEX sarray.c sendmsg.c sarray.h
+initialize_sel SAFE2 sendmsg.c
+narrays MUTEX sarray.c sendmsg.c sarray.h
+nbuckets MUTEX sarray.c sendmsg.c sarray.h
+nindices MUTEX sarray.c sarray.h
+previous_constructors SAFE1 init.c
+proto_class SAFE1 init.c
+unclaimed_categories MUTEX init.c
+unclaimed_proto_list MUTEX init.c
+uninitialized_statics MUTEX init.c
+
+Notes:
+1) Initialized once in unithread mode.
+2) Initialized value will always be same, guaranteed by lock on selector
+ hash table.
+
+
+******************************************************************************
+* Frontend/Backend design:
+
+The design of the Objective-C runtime thread and mutex functions utilizes a
+frontend/backend implementation.
+
+The frontend, as characterized by the files thr.h and thr.c, is a set
+of platform independent structures and functions which represent the
+user interface. Objective-C programs should use these structures and
+functions for their thread and mutex work if they wish to maintain a
+high degree of portability across platforms.
+
+The backend is composed of a file with the necessary code to map the ObjC
+thread and mutex to a platform specific implementation. For example, the
+file thr-solaris.c contains the implementation for Solaris. When you
+configure GCC, it attempts to pick an appropriate backend file for the
+target platform; however, you can override this choice by assign the
+OBJC_THREAD_FILE make variable to the basename of the backend file. This
+is especially useful on platforms which have multiple thread libraries.
+For example:
+
+ make OBJC_THREAD_FILE=thr-posix
+
+would indicate that the generic posix backend file, thr-posix.c, should be
+compiled with the ObjC runtime library. If your platform does not support
+threads then you should specify the OBJC_THREAD_FILE=thr-single backend file
+to compile the ObjC runtime library without thread or mutex support; note
+that programs which rely upon the ObjC thread and mutex functions will
+compile and link correctly but attempting to create a thread or mutex will
+result in an error.
+
+It is questionable whether it is really necessary to have both a
+frontend and backend function for all available functionality. On the
+one hand, it provides a clear, consistent differentiation between what
+is public and what is private with the downside of having the overhead
+of multiple functions calls. For example, the function to have a thread
+yield the processor is objc_thread_yield; in the current implementation
+this produces a function call set:
+
+objc_thread_yield() -> __objc_thread_yield() -> system yield function
+
+This has two extra function calls over calling the platform specific function
+explicitly, but the issue is whether only the overhead of a single function
+is necessary.
+
+objc_thread_yield() -> system yield function
+
+This breaks the public/private dichotomy between the frontend/backend
+for the sake of efficiency. It is possible to just use a preprocessor
+define so as to eliminate the extra function call:
+
+#define objc_thread_yield() __objc_thread_yield()
+
+This has the undesirable effect that if objc_thread_yield is actually
+turned into a function based upon future need; then ObjC programs which
+access the thread functions would need to be recompiled versus just
+being relinked.
+
+******************************************************************************
+* Threads:
+
+The thread system attempts to create multiple threads using whatever
+operating system or library thread support is available. It does
+assume that all system functions are thread safe. Notably this means
+that the system implementation of malloc and free must be thread safe.
+If a system has multiple processors, the threads are configured for
+full parallel processing.
+
+* Backend initialization functions
+
+__objc_init_thread_system(void), int
+ Initialize the thread subsystem. Called once by __objc_exec_class.
+ Return -1 if error otherwise return 0.
+
+__objc_close_thread_system(void), int
+ Closes the thread subsystem, not currently guaranteed to be called.
+ Return -1 if error otherwise return 0.
+
+*****
+* Frontend thread functions
+* User programs should use these functions.
+
+objc_thread_detach(SEL selector, id object, id argument), objc_thread_t
+ Creates and detaches a new thread. The new thread starts by
+ sending the given selector with a single argument to the
+ given object.
+
+objc_thread_set_priority(int priority), int
+ Sets a thread's relative priority within the program. Valid
+ options are:
+
+ OBJC_THREAD_INTERACTIVE_PRIORITY
+ OBJC_THREAD_BACKGROUND_PRIORITY
+ OBJC_THREAD_LOW_PRIORITY
+
+objc_thread_get_priority(void), int
+ Query a thread's priority.
+
+objc_thread_yield(void), void
+ Yields processor to another thread with equal or higher
+ priority. It is up to the system scheduler to determine if
+ the processor is taken or not.
+
+objc_thread_exit(void), int
+ Terminates a thread. If this is the last thread executing
+ then the program will terminate.
+
+objc_thread_id(void), int
+ Returns the current thread's id.
+
+objc_thread_set_data(void *value), int
+ Set a pointer to the thread's local storage. Local storage is
+ thread specific.
+
+objc_thread_get_data(void), void *
+ Returns the pointer to the thread's local storage.
+
+*****
+* Backend thread functions
+* User programs should *NOT* directly call these functions.
+
+__objc_thread_detach(void (*func)(void *arg), void *arg), objc_thread_t
+ Spawns a new thread executing func, called by objc_thread_detach.
+ Return NULL if error otherwise return thread id.
+
+__objc_thread_set_priority(int priority), int
+ Set the thread's priority, called by objc_thread_set_priority.
+ Return -1 if error otherwise return 0.
+
+__objc_thread_get_priority(void), int
+ Query a thread's priority, called by objc_thread_get_priority.
+ Return -1 if error otherwise return the priority.
+
+__objc_thread_yield(void), void
+ Yields the processor, called by objc_thread_yield.
+
+__objc_thread_exit(void), int
+ Terminates the thread, called by objc_thread_exit.
+ Return -1 if error otherwise function does not return.
+
+__objc_thread_id(void), objc_thread_t
+ Returns the current thread's id, called by objc_thread_id.
+ Return -1 if error otherwise return thread id.
+
+__objc_thread_set_data(void *value), int
+ Set pointer for thread local storage, called by objc_thread_set_data.
+ Returns -1 if error otherwise return 0.
+
+__objc_thread_get_data(void), void *
+ Returns the pointer to the thread's local storage.
+ Returns NULL if error, called by objc_thread_get_data.
+
+
+******************************************************************************
+* Mutexes:
+
+Mutexes can be locked recursively. Each locked mutex remembers
+its owner (by thread id) and how many times it has been locked. The
+last unlock on a mutex removes the system lock and allows other
+threads to access the mutex.
+
+*****
+* Frontend mutex functions
+* User programs should use these functions.
+
+objc_mutex_allocate(void), objc_mutex_t
+ Allocates a new mutex. Mutex is initially unlocked.
+ Return NULL if error otherwise return mutex pointer.
+
+objc_mutex_deallocate(objc_mutex_t mutex), int
+ Free a mutex. Before freeing the mutex, makes sure that no
+ one else is using it.
+ Return -1 if error otherwise return 0.
+
+objc_mutex_lock(objc_mutex_t mutex), int
+ Locks a mutex. As mentioned earlier, the same thread may call
+ this routine repeatedly.
+ Return -1 if error otherwise return 0.
+
+objc_mutex_trylock(objc_mutex_t mutex), int
+ Attempts to lock a mutex. If lock on mutex can be acquired
+ then function operates exactly as objc_mutex_lock.
+ Return -1 if failed to acquire lock otherwise return 0.
+
+objc_mutex_unlock(objc_mutex_t mutex), int
+ Unlocks the mutex by one level. Other threads may not acquire
+ the mutex until this thread has released all locks on it.
+ Return -1 if error otherwise return 0.
+
+*****
+* Backend mutex functions
+* User programs should *NOT* directly call these functions.
+
+__objc_mutex_allocate(objc_mutex_t mutex), int
+ Allocates a new mutex, called by objc_mutex_allocate.
+ Return -1 if error otherwise return 0.
+
+__objc_mutex_deallocate(objc_mutex_t mutex), int
+ Free a mutex, called by objc_mutex_deallocate.
+ Return -1 if error otherwise return 0.
+
+__objc_mutex_lock(objc_mutex_t mutex), int
+ Locks a mutex, called by objc_mutex_lock.
+ Return -1 if error otherwise return 0.
+
+__objc_mutex_trylock(objc_mutex_t mutex), int
+ Attempts to lock a mutex, called by objc_mutex_trylock.
+ Return -1 if failed to acquire lock or error otherwise return 0.
+
+__objc_mutex_unlock(objc_mutex_t mutex), int
+ Unlocks the mutex, called by objc_mutex_unlock.
+ Return -1 if error otherwise return 0.
+
+******************************************************************************
+* Condition Mutexes:
+
+Mutexes can be locked recursively. Each locked mutex remembers
+its owner (by thread id) and how many times it has been locked. The
+last unlock on a mutex removes the system lock and allows other
+threads to access the mutex.
+
+*
+* Frontend condition mutex functions
+* User programs should use these functions.
+*
+
+objc_condition_allocate(void), objc_condition_t
+ Allocate a condition mutex.
+ Return NULL if error otherwise return condition pointer.
+
+objc_condition_deallocate(objc_condition_t condition), int
+ Deallocate a condition. Note that this includes an implicit
+ condition_broadcast to insure that waiting threads have the
+ opportunity to wake. It is legal to dealloc a condition only
+ if no other thread is/will be using it. Does NOT check for
+ other threads waiting but just wakes them up.
+ Return -1 if error otherwise return 0.
+
+objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int
+ Wait on the condition unlocking the mutex until objc_condition_signal()
+ or objc_condition_broadcast() are called for the same condition. The
+ given mutex *must* have the depth 1 so that it can be unlocked
+ here, for someone else can lock it and signal/broadcast the condition.
+ The mutex is used to lock access to the shared data that make up the
+ "condition" predicate.
+ Return -1 if error otherwise return 0.
+
+objc_condition_broadcast(objc_condition_t condition), int
+ Wake up all threads waiting on this condition. It is recommended that
+ the called would lock the same mutex as the threads in
+ objc_condition_wait before changing the "condition predicate"
+ and make this call and unlock it right away after this call.
+ Return -1 if error otherwise return 0.
+
+objc_condition_signal(objc_condition_t condition), int
+ Wake up one thread waiting on this condition.
+ Return -1 if error otherwise return 0.
+
+*
+* Backend condition mutex functions
+* User programs should *NOT* directly call these functions.
+*
+
+__objc_condition_allocate(objc_condition_t condition), int
+ Allocate a condition mutex, called by objc_condition_allocate.
+ Return -1 if error otherwise return 0.
+
+__objc_condition_deallocate(objc_condition_t condition), int
+ Deallocate a condition, called by objc_condition_deallocate.
+ Return -1 if error otherwise return 0.
+
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int
+ Wait on the condition, called by objc_condition_wait.
+ Return -1 if error otherwise return 0 when condition is met.
+
+__objc_condition_broadcast(objc_condition_t condition), int
+ Wake up all threads waiting on this condition.
+ Called by objc_condition_broadcast.
+ Return -1 if error otherwise return 0.
+
+__objc_condition_signal(objc_condition_t condition), int
+ Wake up one thread waiting on this condition.
+ Called by objc_condition_signal.
+ Return -1 if error otherwise return 0.
diff --git a/gnu/usr.bin/gcc/objc/THREADS.MACH b/gnu/usr.bin/gcc/objc/THREADS.MACH
new file mode 100644
index 00000000000..55de6637866
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/THREADS.MACH
@@ -0,0 +1,23 @@
+This readme refers to the file thr-mach.c.
+
+Under mach, thread priorities are kinda strange-- any given thread has
+a MAXIMUM priority and a BASE priority. The BASE priority is the
+current priority of the thread and the MAXIMUM is the maximum possible
+priority the thread can assume. The developer can lower, but never
+raise the maximum priority.
+
+The gcc concept of thread priorities is that they run at one of three
+levels; interactive, background, and low.
+
+Under mach, this is translated to:
+
+interactive -- set priority to maximum
+background -- set priority to 2/3 of maximum
+low -- set priority to 1/3 of maximum
+
+This means that it is possible for a thread with the priority of
+interactive to actually run at a lower priority than another thread
+with a background, or even low, priority if the developer has modified
+the maximum priority.
+
+
diff --git a/gnu/usr.bin/gcc/objc/config-lang.in b/gnu/usr.bin/gcc/objc/config-lang.in
new file mode 100644
index 00000000000..736ba73b4ec
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/config-lang.in
@@ -0,0 +1,37 @@
+# Top level configure fragment for the GNU Objective-C Runtime Library.
+# Copyright (C) 1997 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.
+
+# Configure looks for the existence of this file to auto-config each language.
+# We define several parameters used by configure:
+#
+# language - name of language as it would appear in $(LANGUAGES)
+# compilers - value to add to $(COMPILERS)
+# stagestuff - files to add to $(STAGESTUFF)
+# diff_excludes - files to ignore when building diffs between two versions.
+
+language="objc"
+
+compilers="cc1obj\$(exeext)"
+
+stagestuff=""
+
+diff_excludes=""
+
+echo "Using \`$srcdir/objc/thr-${thread_file}.c' as Objective-C Runtime thread file."
diff --git a/gnu/usr.bin/gcc/objc/libobjc.def b/gnu/usr.bin/gcc/objc/libobjc.def
new file mode 100644
index 00000000000..a4a6049e816
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/libobjc.def
@@ -0,0 +1,161 @@
+; GNU Objective C Runtime DLL Export Definitions
+; Copyright (C) 1997 Free Software Foundation, Inc.
+; Contributed by Scott Christley <scottc@net-community.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.
+
+LIBRARY libobjc
+EXPORTS
+search_for_method_in_list
+objc_get_uninstalled_dtable
+hash_is_key_in_hash
+objc_verror
+_objc_load_callback
+objc_malloc
+objc_atomic_malloc
+objc_valloc
+objc_realloc
+objc_calloc
+objc_free
+__objc_init_thread_system
+objc_mutex_allocate
+objc_mutex_deallocate
+objc_mutex_lock
+objc_mutex_trylock
+objc_mutex_unlock
+objc_thread_detach
+objc_thread_exit
+objc_thread_get_data
+objc_thread_get_priority
+objc_thread_id
+objc_thread_set_data
+objc_thread_set_priority
+objc_thread_yield
+__objc_class_name_Object
+__objc_class_name_Protocol
+__objc_class_name_NXConstantString
+objc_error
+__objc_object_alloc
+__objc_object_copy
+__objc_object_dispose
+class_create_instance
+object_copy
+object_dispose
+__objc_init_selector_tables
+__objc_register_selectors_from_class
+__sel_register_typed_name
+sel_get_any_typed_uid
+sel_get_any_uid
+sel_get_name
+sel_get_type
+sel_get_typed_uid
+sel_get_uid
+sel_is_mapped
+sel_register_name
+sel_register_typed_name
+sel_types_match
+method_get_first_argument
+method_get_next_argument
+method_get_nth_argument
+method_get_number_of_arguments
+method_get_sizeof_arguments
+objc_aligned_size
+objc_alignof_type
+objc_get_type_qualifiers
+objc_promoted_size
+objc_sizeof_type
+objc_skip_argspec
+objc_skip_offset
+objc_skip_type_qualifiers
+objc_skip_typespec
+__objc_read_nbyte_uint
+__objc_read_nbyte_ulong
+__objc_write_class
+__objc_write_object
+__objc_write_selector
+objc_close_typed_stream
+objc_end_of_typed_stream
+objc_flush_typed_stream
+objc_get_stream_class_version
+objc_open_typed_stream
+objc_open_typed_stream_for_file
+objc_read_array
+objc_read_char
+objc_read_int
+objc_read_long
+objc_read_object
+objc_read_selector
+objc_read_short
+objc_read_string
+objc_read_type
+objc_read_types
+objc_read_unsigned_char
+objc_read_unsigned_int
+objc_read_unsigned_long
+objc_read_unsigned_short
+objc_write_array
+objc_write_char
+objc_write_int
+objc_write_long
+objc_write_object
+objc_write_object_reference
+objc_write_root_object
+objc_write_selector
+objc_write_short
+objc_write_string
+objc_write_string_atomic
+objc_write_type
+objc_write_types
+objc_write_unsigned_char
+objc_write_unsigned_int
+objc_write_unsigned_long
+objc_write_unsigned_short
+__objc_exec_class
+__objc_init_dispatch_tables
+__objc_install_premature_dtable
+__objc_print_dtable_stats
+__objc_responds_to
+__objc_update_dispatch_table_for_class
+class_add_method_list
+class_get_class_method
+class_get_instance_method
+get_imp
+nil_method
+objc_msg_lookup
+objc_msg_lookup_super
+objc_msg_sendv
+__objc_add_class_to_hash
+__objc_init_class_tables
+__objc_resolve_class_links
+class_pose_as
+objc_get_class
+objc_get_meta_class
+objc_lookup_class
+objc_next_class
+sarray_at_put
+sarray_at_put_safe
+sarray_free
+sarray_lazy_copy
+sarray_new
+sarray_realloc
+sarray_remove_garbage
+hash_add
+hash_delete
+hash_new
+hash_next
+hash_remove
+hash_value_for_key
diff --git a/gnu/usr.bin/gcc/objc/libobjc_entry.c b/gnu/usr.bin/gcc/objc/libobjc_entry.c
new file mode 100644
index 00000000000..2d584ab3c1e
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/libobjc_entry.c
@@ -0,0 +1,55 @@
+/* GNU Objective C Runtime DLL Entry
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Scott Christley <scottc@net-community.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. */
+
+/* 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. */
+
+#include <windows.h>
+
+/*
+ DLL entry function for Objective-C Runtime library
+ This function gets called everytime a process/thread attaches to DLL
+ */
+WINBOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call,
+ LPVOID lpReserved)
+{
+ switch(ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ break;
+ case DLL_PROCESS_DETACH:
+ break;
+ case DLL_THREAD_ATTACH:
+ break;
+ case DLL_THREAD_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
+/*
+ This section terminates the list of imports under GCC. If you do not
+ include this then you will have problems when linking with DLLs.
+ */
+asm (".section .idata$3\n" ".long 0,0,0,0,0,0,0,0");
diff --git a/gnu/usr.bin/gcc/objc/linking.m b/gnu/usr.bin/gcc/objc/linking.m
new file mode 100644
index 00000000000..8ecca028110
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/linking.m
@@ -0,0 +1,40 @@
+/* Force linking of classes required by Objective C runtime.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Ovidiu Predescu (ovidiu@net-community.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. */
+
+/* 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. */
+
+#include <objc/Object.h>
+#include <objc/NXConstStr.h>
+
+/* Generate references to Object and NXConstanstString classes since they are
+ needed by the runtime system to run correctly. */
+
+
+void __objc_linking (void)
+{
+ [Object name];
+ [NXConstantString name];
+}
+
diff --git a/gnu/usr.bin/gcc/objc/nil_method.c b/gnu/usr.bin/gcc/objc/nil_method.c
new file mode 100644
index 00000000000..1b6212826bd
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/nil_method.c
@@ -0,0 +1,40 @@
+/* GNU Objective C Runtime nil receiver function
+ Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
+ Contributed by Kresten Krab Thorup
+
+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. */
+
+/* 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 is the nil method, the function that is called when the receiver
+ of a method is nil */
+
+#include "runtime.h"
+
+id
+nil_method(id receiver, SEL op, ...)
+{
+ return receiver;
+}
+
+
+
+
diff --git a/gnu/usr.bin/gcc/objc/objc-act.c b/gnu/usr.bin/gcc/objc/objc-act.c
new file mode 100644
index 00000000000..6b0de8d3556
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/objc-act.c
@@ -0,0 +1,8410 @@
+/* Implement classes and message passing for Objective C.
+ Copyright (C) 1992, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ Contributed by Steve Naroff.
+
+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. */
+
+/* Purpose: This module implements the Objective-C 4.0 language.
+
+ compatibility issues (with the Stepstone translator):
+
+ - does not recognize the following 3.3 constructs.
+ @requires, @classes, @messages, = (...)
+ - methods with variable arguments must conform to ANSI standard.
+ - tagged structure definitions that appear in BOTH the interface
+ and implementation are not allowed.
+ - public/private: all instance variables are public within the
+ context of the implementation...I consider this to be a bug in
+ the translator.
+ - statically allocated objects are not supported. the user will
+ receive an error if this service is requested.
+
+ code generation `options':
+
+ - OBJC_INT_SELECTORS */
+
+#include "config.h"
+#include <stdio.h>
+#include "tree.h"
+#include "c-tree.h"
+#include "c-lex.h"
+#include "flags.h"
+#include "objc-act.h"
+#include "input.h"
+#include "except.h"
+#include "function.h"
+#include <string.h>
+#include "output.h"
+
+/* This is the default way of generating a method name. */
+/* I am not sure it is really correct.
+ Perhaps there's a danger that it will make name conflicts
+ if method names contain underscores. -- rms. */
+#ifndef OBJC_GEN_METHOD_LABEL
+#define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
+ do { \
+ char *temp; \
+ sprintf ((BUF), "_%s_%s_%s_%s", \
+ ((IS_INST) ? "i" : "c"), \
+ (CLASS_NAME), \
+ ((CAT_NAME)? (CAT_NAME) : ""), \
+ (SEL_NAME)); \
+ for (temp = (BUF); *temp; temp++) \
+ if (*temp == ':') *temp = '_'; \
+ } while (0)
+#endif
+
+/* These need specifying. */
+#ifndef OBJC_FORWARDING_STACK_OFFSET
+#define OBJC_FORWARDING_STACK_OFFSET 0
+#endif
+
+#ifndef OBJC_FORWARDING_MIN_OFFSET
+#define OBJC_FORWARDING_MIN_OFFSET 0
+#endif
+
+/* Define the special tree codes that we use. */
+
+/* Table indexed by tree code giving a string containing a character
+ classifying the tree code. Possibilities are
+ t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
+
+#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
+
+char *objc_tree_code_type[] = {
+ "x",
+#include "objc-tree.def"
+};
+#undef DEFTREECODE
+
+/* Table indexed by tree code giving number of expression
+ operands beyond the fixed part of the node structure.
+ Not used for types or decls. */
+
+#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
+
+int objc_tree_code_length[] = {
+ 0,
+#include "objc-tree.def"
+};
+#undef DEFTREECODE
+
+/* Names of tree components.
+ Used for printing out the tree and error messages. */
+#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
+
+char *objc_tree_code_name[] = {
+ "@@dummy",
+#include "objc-tree.def"
+};
+#undef DEFTREECODE
+
+/* Set up for use of obstacks. */
+
+#include "obstack.h"
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+
+/* This obstack is used to accumulate the encoding of a data type. */
+static struct obstack util_obstack;
+/* This points to the beginning of obstack contents,
+ so we can free the whole contents. */
+char *util_firstobj;
+
+/* List of classes with list of their static instances. */
+static tree objc_static_instances = NULL_TREE;
+
+/* The declaration of the array administrating the static instances. */
+static tree static_instances_decl = NULL_TREE;
+
+/* for encode_method_def */
+#include "rtl.h"
+#include "c-parse.h"
+
+#define OBJC_VERSION (flag_next_runtime ? 5 : 8)
+#define PROTOCOL_VERSION 2
+
+#define OBJC_ENCODE_INLINE_DEFS 0
+#define OBJC_ENCODE_DONT_INLINE_DEFS 1
+
+/*** Private Interface (procedures) ***/
+
+/* Used by compile_file. */
+
+static void init_objc PROTO((void));
+static void finish_objc PROTO((void));
+
+/* Code generation. */
+
+static void synth_module_prologue PROTO((void));
+static tree build_constructor PROTO((tree, tree));
+static char *build_module_descriptor PROTO((void));
+static tree init_module_descriptor PROTO((tree));
+static tree build_objc_method_call PROTO((int, tree, tree,
+ tree, tree, tree));
+static void generate_strings PROTO((void));
+static tree get_proto_encoding PROTO((tree));
+static void build_selector_translation_table PROTO((void));
+static tree build_ivar_chain PROTO((tree, int));
+
+static tree objc_add_static_instance PROTO((tree, tree));
+
+static tree build_ivar_template PROTO((void));
+static tree build_method_template PROTO((void));
+static tree build_private_template PROTO((tree));
+static void build_class_template PROTO((void));
+static void build_selector_template PROTO((void));
+static void build_category_template PROTO((void));
+static tree build_super_template PROTO((void));
+static tree build_category_initializer PROTO((tree, tree, tree,
+ tree, tree, tree));
+static tree build_protocol_initializer PROTO((tree, tree, tree,
+ tree, tree));
+
+static void synth_forward_declarations PROTO((void));
+static void generate_ivar_lists PROTO((void));
+static void generate_dispatch_tables PROTO((void));
+static void generate_shared_structures PROTO((void));
+static tree generate_protocol_list PROTO((tree));
+static void generate_forward_declaration_to_string_table PROTO((void));
+static void build_protocol_reference PROTO((tree));
+
+static tree init_selector PROTO((int));
+static tree build_keyword_selector PROTO((tree));
+static tree synth_id_with_class_suffix PROTO((char *, tree));
+
+/* From expr.c */
+extern int apply_args_register_offset PROTO((int));
+
+static void generate_static_references PROTO((void));
+static int check_methods_accessible PROTO((tree, tree,
+ int));
+static void encode_aggregate_within PROTO((tree, int, int,
+ char, char));
+
+/* We handle printing method names ourselves for ObjC */
+extern char *(*decl_printable_name) ();
+
+/* Misc. bookkeeping */
+
+typedef struct hashed_entry *hash;
+typedef struct hashed_attribute *attr;
+
+struct hashed_attribute
+{
+ attr next;
+ tree value;
+};
+struct hashed_entry
+{
+ attr list;
+ hash next;
+ tree key;
+};
+
+static void hash_init PROTO((void));
+static void hash_enter PROTO((hash *, tree));
+static hash hash_lookup PROTO((hash *, tree));
+static void hash_add_attr PROTO((hash, tree));
+static tree lookup_method PROTO((tree, tree));
+static tree lookup_instance_method_static PROTO((tree, tree));
+static tree lookup_class_method_static PROTO((tree, tree));
+static tree add_class PROTO((tree));
+static void add_category PROTO((tree, tree));
+
+enum string_section
+{
+ class_names, /* class, category, protocol, module names */
+ meth_var_names, /* method and variable names */
+ meth_var_types /* method and variable type descriptors */
+};
+
+static tree add_objc_string PROTO((tree,
+ enum string_section));
+static tree get_objc_string_decl PROTO((tree,
+ enum string_section));
+static tree build_objc_string_decl PROTO((tree,
+ enum string_section));
+static tree build_selector_reference_decl PROTO((tree));
+
+/* Protocol additions. */
+
+static tree add_protocol PROTO((tree));
+static tree lookup_protocol PROTO((tree));
+static tree lookup_and_install_protocols PROTO((tree));
+
+/* Type encoding. */
+
+static void encode_type_qualifiers PROTO((tree));
+static void encode_pointer PROTO((tree, int, int));
+static void encode_array PROTO((tree, int, int));
+static void encode_aggregate PROTO((tree, int, int));
+static void encode_bitfield PROTO((int, int));
+static void encode_type PROTO((tree, int, int));
+static void encode_field_decl PROTO((tree, int, int));
+
+static void really_start_method PROTO((tree, tree));
+static int comp_method_with_proto PROTO((tree, tree));
+static int comp_proto_with_proto PROTO((tree, tree));
+static tree get_arg_type_list PROTO((tree, int, int));
+static tree expr_last PROTO((tree));
+
+/* Utilities for debugging and error diagnostics. */
+
+static void warn_with_method PROTO((char *, int, tree));
+static void error_with_ivar PROTO((char *, tree, tree));
+static char *gen_method_decl PROTO((tree, char *));
+static char *gen_declaration PROTO((tree, char *));
+static char *gen_declarator PROTO((tree, char *, char *));
+static int is_complex_decl PROTO((tree));
+static void adorn_decl PROTO((tree, char *));
+static void dump_interface PROTO((FILE *, tree));
+
+/* Everything else. */
+
+static void objc_fatal PROTO((void));
+static tree define_decl PROTO((tree, tree));
+static tree lookup_method_in_protocol_list PROTO((tree, tree, int));
+static tree lookup_protocol_in_reflist PROTO((tree, tree));
+static tree create_builtin_decl PROTO((enum tree_code,
+ tree, char *));
+static tree my_build_string PROTO((int, char *));
+static void build_objc_symtab_template PROTO((void));
+static tree init_def_list PROTO((tree));
+static tree init_objc_symtab PROTO((tree));
+static void forward_declare_categories PROTO((void));
+static void generate_objc_symtab_decl PROTO((void));
+static tree build_selector PROTO((tree));
+static tree build_msg_pool_reference PROTO((int));
+static tree build_typed_selector_reference PROTO((tree, tree));
+static tree build_selector_reference PROTO((tree));
+static tree build_class_reference_decl PROTO((tree));
+static void add_class_reference PROTO((tree));
+static tree objc_copy_list PROTO((tree, tree *));
+static tree build_protocol_template PROTO((void));
+static tree build_descriptor_table_initializer PROTO((tree, tree));
+static tree build_method_prototype_list_template PROTO((tree, int));
+static tree build_method_prototype_template PROTO((void));
+static int forwarding_offset PROTO((tree));
+static tree encode_method_prototype PROTO((tree, tree));
+static tree generate_descriptor_table PROTO((tree, char *, int, tree, tree));
+static void generate_method_descriptors PROTO((tree));
+static tree build_tmp_function_decl PROTO((void));
+static void hack_method_prototype PROTO((tree, tree));
+static void generate_protocol_references PROTO((tree));
+static void generate_protocols PROTO((void));
+static void check_ivars PROTO((tree, tree));
+static tree build_ivar_list_template PROTO((tree, int));
+static tree build_method_list_template PROTO((tree, int));
+static tree build_ivar_list_initializer PROTO((tree, tree));
+static tree generate_ivars_list PROTO((tree, char *,
+ int, tree));
+static tree build_dispatch_table_initializer PROTO((tree, tree));
+static tree generate_dispatch_table PROTO((tree, char *,
+ int, tree));
+static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree,
+ tree, int, tree, tree,
+ tree));
+static void generate_category PROTO((tree));
+static int is_objc_type_qualifier PROTO((tree));
+static tree adjust_type_for_id_default PROTO((tree));
+static tree check_duplicates PROTO((hash));
+static tree receiver_is_class_object PROTO((tree));
+static int check_methods PROTO((tree, tree, int));
+static int conforms_to_protocol PROTO((tree, tree));
+static void check_protocols PROTO((tree, char *, char *));
+static tree encode_method_def PROTO((tree));
+static void gen_declspecs PROTO((tree, char *, int));
+static void generate_classref_translation_entry PROTO((tree));
+static void handle_class_ref PROTO((tree));
+
+/*** Private Interface (data) ***/
+
+/* Reserved tag definitions. */
+
+#define TYPE_ID "id"
+#define TAG_OBJECT "objc_object"
+#define TAG_CLASS "objc_class"
+#define TAG_SUPER "objc_super"
+#define TAG_SELECTOR "objc_selector"
+
+#define UTAG_CLASS "_objc_class"
+#define UTAG_IVAR "_objc_ivar"
+#define UTAG_IVAR_LIST "_objc_ivar_list"
+#define UTAG_METHOD "_objc_method"
+#define UTAG_METHOD_LIST "_objc_method_list"
+#define UTAG_CATEGORY "_objc_category"
+#define UTAG_MODULE "_objc_module"
+#define UTAG_STATICS "_objc_statics"
+#define UTAG_SYMTAB "_objc_symtab"
+#define UTAG_SUPER "_objc_super"
+#define UTAG_SELECTOR "_objc_selector"
+
+#define UTAG_PROTOCOL "_objc_protocol"
+#define UTAG_PROTOCOL_LIST "_objc_protocol_list"
+#define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
+#define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
+
+#define STRING_OBJECT_CLASS_NAME "NXConstantString"
+#define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
+
+static char *TAG_GETCLASS;
+static char *TAG_GETMETACLASS;
+static char *TAG_MSGSEND;
+static char *TAG_MSGSENDSUPER;
+static char *TAG_EXECCLASS;
+
+/* Set by `continue_class' and checked by `is_public'. */
+
+#define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
+#define TYPED_OBJECT(type) \
+ (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
+
+/* Some commonly used instances of "identifier_node". */
+
+static tree self_id, ucmd_id;
+static tree unused_list;
+
+static tree self_decl, umsg_decl, umsg_super_decl;
+static tree objc_get_class_decl, objc_get_meta_class_decl;
+
+static tree super_type, selector_type, id_type, objc_class_type;
+static tree instance_type, protocol_type;
+
+/* Type checking macros. */
+
+#define IS_ID(TYPE) \
+ (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
+#define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
+ (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
+#define IS_SUPER(TYPE) \
+ (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
+
+static tree class_chain = NULL_TREE;
+static tree alias_chain = NULL_TREE;
+static tree interface_chain = NULL_TREE;
+static tree protocol_chain = NULL_TREE;
+
+/* Chains to manage selectors that are referenced and defined in the
+ module. */
+
+static tree cls_ref_chain = NULL_TREE; /* Classes referenced. */
+static tree sel_ref_chain = NULL_TREE; /* Selectors referenced. */
+
+/* Chains to manage uniquing of strings. */
+
+static tree class_names_chain = NULL_TREE;
+static tree meth_var_names_chain = NULL_TREE;
+static tree meth_var_types_chain = NULL_TREE;
+
+/* Hash tables to manage the global pool of method prototypes. */
+
+static hash *nst_method_hash_list = 0;
+static hash *cls_method_hash_list = 0;
+
+/* Backend data declarations. */
+
+static tree UOBJC_SYMBOLS_decl;
+static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl;
+static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl;
+static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl;
+static tree UOBJC_SELECTOR_TABLE_decl;
+static tree UOBJC_MODULES_decl;
+static tree UOBJC_STRINGS_decl;
+
+/* The following are used when compiling a class implementation.
+ implementation_template will normally be an interface, however if
+ none exists this will be equal to implementation_context...it is
+ set in start_class. */
+
+static tree implementation_context = NULL_TREE;
+static tree implementation_template = NULL_TREE;
+
+struct imp_entry
+{
+ struct imp_entry *next;
+ tree imp_context;
+ tree imp_template;
+ tree class_decl; /* _OBJC_CLASS_<my_name>; */
+ tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
+};
+
+static void handle_impent PROTO((struct imp_entry *));
+
+static struct imp_entry *imp_list = 0;
+static int imp_count = 0; /* `@implementation' */
+static int cat_count = 0; /* `@category' */
+
+static tree objc_class_template, objc_category_template, uprivate_record;
+static tree objc_protocol_template, objc_selector_template;
+static tree ucls_super_ref, uucls_super_ref;
+
+static tree objc_method_template, objc_ivar_template;
+static tree objc_symtab_template, objc_module_template;
+static tree objc_super_template, objc_object_reference;
+
+static tree objc_object_id, objc_class_id, objc_id_id;
+static tree constant_string_id;
+static tree constant_string_type;
+static tree UOBJC_SUPER_decl;
+
+static tree method_context = NULL_TREE;
+static int method_slot = 0; /* Used by start_method_def, */
+
+#define BUFSIZE 1024
+
+static char *errbuf; /* Buffer for error diagnostics */
+
+/* Data imported from tree.c. */
+
+extern enum debug_info_type write_symbols;
+
+/* Data imported from toplev.c. */
+
+extern char *dump_base_name;
+
+/* Generate code for GNU or NeXT runtime environment. */
+
+#ifdef NEXT_OBJC_RUNTIME
+int flag_next_runtime = 1;
+#else
+int flag_next_runtime = 0;
+#endif
+
+int flag_typed_selectors;
+
+/* Open and close the file for outputting class declarations, if requested. */
+
+int flag_gen_declaration = 0;
+
+FILE *gen_declaration_file;
+
+/* Warn if multiple methods are seen for the same selector, but with
+ different argument types. */
+
+int warn_selector = 0;
+
+/* Warn if methods required by a protocol are not implemented in the
+ class adopting it. When turned off, methods inherited to that
+ class are also considered implemented */
+
+int flag_warn_protocol = 1;
+
+/* Tells "encode_pointer/encode_aggregate" whether we are generating
+ type descriptors for instance variables (as opposed to methods).
+ Type descriptors for instance variables contain more information
+ than methods (for static typing and embedded structures). This
+ was added to support features being planned for dbkit2. */
+
+static int generating_instance_variables = 0;
+
+/* Tells the compiler that this is a special run. Do not perform
+ any compiling, instead we are to test some platform dependent
+ features and output a C header file with appropriate definitions. */
+
+static int print_struct_values = 0;
+
+/* Some platforms pass small structures through registers versus through
+ an invisible pointer. Determine at what size structure is the
+ transition point between the two possibilities. */
+
+void
+generate_struct_by_value_array ()
+{
+ tree type;
+ tree field_decl, field_decl_chain;
+ int i, j;
+ int aggregate_in_mem[32];
+ int found = 0;
+
+ /* Presumbaly no platform passes 32 byte structures in a register. */
+ for (i = 1; i < 32; i++)
+ {
+ char buffer[5];
+
+ /* Create an unnamed struct that has `i' character components */
+ type = start_struct (RECORD_TYPE, NULL_TREE);
+
+ strcpy (buffer, "c1");
+ field_decl = create_builtin_decl (FIELD_DECL,
+ char_type_node,
+ buffer);
+ field_decl_chain = field_decl;
+
+ for (j = 1; j < i; j++)
+ {
+ sprintf (buffer, "c%d", j + 1);
+ field_decl = create_builtin_decl (FIELD_DECL,
+ char_type_node,
+ buffer);
+ chainon (field_decl_chain, field_decl);
+ }
+ finish_struct (type, field_decl_chain, NULL_TREE);
+
+ aggregate_in_mem[i] = aggregate_value_p (type);
+ if (!aggregate_in_mem[i])
+ found = 1;
+ }
+
+ /* We found some structures that are returned in registers instead of memory
+ so output the necessary data. */
+ if (found)
+ {
+ for (i = 31; i >= 0; i--)
+ if (!aggregate_in_mem[i])
+ break;
+ printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
+
+ /* The first member of the structure is always 0 because we don't handle
+ structures with 0 members */
+ printf ("static int struct_forward_array[] = {\n 0");
+
+ for (j = 1; j <= i; j++)
+ printf (", %d", aggregate_in_mem[j]);
+ printf ("\n};\n");
+ }
+
+ exit (0);
+}
+
+void
+lang_init ()
+{
+#if !USE_CPPLIB
+ /* The beginning of the file is a new line; check for #.
+ With luck, we discover the real source file's name from that
+ and put it in input_filename. */
+ ungetc (check_newline (), finput);
+#endif
+
+ /* The line number can be -1 if we had -g3 and the input file
+ had a directive specifying line 0. But we want predefined
+ functions to have a line number of 0, not -1. */
+ if (lineno == -1)
+ lineno = 0;
+
+ /* If gen_declaration desired, open the output file. */
+ if (flag_gen_declaration)
+ {
+ int dump_base_name_length = strlen (dump_base_name);
+ register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
+ strcpy (dumpname, dump_base_name);
+ strcat (dumpname, ".decl");
+ gen_declaration_file = fopen (dumpname, "w");
+ if (gen_declaration_file == 0)
+ pfatal_with_name (dumpname);
+ }
+
+ if (flag_next_runtime)
+ {
+ TAG_GETCLASS = "objc_getClass";
+ TAG_GETMETACLASS = "objc_getMetaClass";
+ TAG_MSGSEND = "objc_msgSend";
+ TAG_MSGSENDSUPER = "objc_msgSendSuper";
+ TAG_EXECCLASS = "__objc_execClass";
+ }
+ else
+ {
+ TAG_GETCLASS = "objc_get_class";
+ TAG_GETMETACLASS = "objc_get_meta_class";
+ TAG_MSGSEND = "objc_msg_lookup";
+ TAG_MSGSENDSUPER = "objc_msg_lookup_super";
+ TAG_EXECCLASS = "__objc_exec_class";
+ flag_typed_selectors = 1;
+ }
+
+ if (doing_objc_thang)
+ init_objc ();
+
+ if (print_struct_values)
+ generate_struct_by_value_array ();
+}
+
+static void
+objc_fatal ()
+{
+ fatal ("Objective-C text in C source file");
+}
+
+void
+finish_file ()
+{
+ if (doing_objc_thang)
+ finish_objc (); /* Objective-C finalization */
+
+ if (gen_declaration_file)
+ fclose (gen_declaration_file);
+}
+
+void
+lang_finish ()
+{
+}
+
+char *
+lang_identify ()
+{
+ return "objc";
+}
+
+int
+lang_decode_option (p)
+ char *p;
+{
+ if (!strcmp (p, "-lang-objc"))
+ doing_objc_thang = 1;
+ else if (!strcmp (p, "-gen-decls"))
+ flag_gen_declaration = 1;
+ else if (!strcmp (p, "-Wselector"))
+ warn_selector = 1;
+ else if (!strcmp (p, "-Wno-selector"))
+ warn_selector = 0;
+ else if (!strcmp (p, "-Wprotocol"))
+ flag_warn_protocol = 1;
+ else if (!strcmp (p, "-Wno-protocol"))
+ flag_warn_protocol = 0;
+ else if (!strcmp (p, "-fgnu-runtime"))
+ flag_next_runtime = 0;
+ else if (!strcmp (p, "-fno-next-runtime"))
+ flag_next_runtime = 0;
+ else if (!strcmp (p, "-fno-gnu-runtime"))
+ flag_next_runtime = 1;
+ else if (!strcmp (p, "-fnext-runtime"))
+ flag_next_runtime = 1;
+ else if (!strcmp (p, "-print-objc-runtime-info"))
+ print_struct_values = 1;
+ else
+ return c_decode_option (p);
+
+ return 1;
+}
+
+static tree
+define_decl (declarator, declspecs)
+ tree declarator;
+ tree declspecs;
+{
+ tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE);
+ finish_decl (decl, NULL_TREE, NULL_TREE);
+ return decl;
+}
+
+/* Return 1 if LHS and RHS are compatible types for assignment or
+ various other operations. Return 0 if they are incompatible, and
+ return -1 if we choose to not decide. When the operation is
+ REFLEXIVE, check for compatibility in either direction.
+
+ For statically typed objects, an assignment of the form `a' = `b'
+ is permitted if:
+
+ `a' is of type "id",
+ `a' and `b' are the same class type, or
+ `a' and `b' are of class types A and B such that B is a descendant of A. */
+
+int
+maybe_objc_comptypes (lhs, rhs, reflexive)
+ tree lhs, rhs;
+ int reflexive;
+{
+ if (doing_objc_thang)
+ return objc_comptypes (lhs, rhs, reflexive);
+ return -1;
+}
+
+static tree
+lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
+ tree rproto_list;
+ tree sel_name;
+ int class_meth;
+{
+ tree rproto, p;
+ tree fnd = 0;
+
+ for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
+ {
+ p = TREE_VALUE (rproto);
+
+ if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
+ {
+ if ((fnd = lookup_method (class_meth
+ ? PROTOCOL_CLS_METHODS (p)
+ : PROTOCOL_NST_METHODS (p), sel_name)))
+ ;
+ else if (PROTOCOL_LIST (p))
+ fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
+ sel_name, class_meth);
+ }
+ else
+ ; /* An identifier...if we could not find a protocol. */
+
+ if (fnd)
+ return fnd;
+ }
+
+ return 0;
+}
+
+static tree
+lookup_protocol_in_reflist (rproto_list, lproto)
+ tree rproto_list;
+ tree lproto;
+{
+ tree rproto, p;
+
+ /* Make sure the protocol is support by the object on the rhs. */
+ if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
+ {
+ tree fnd = 0;
+ for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
+ {
+ p = TREE_VALUE (rproto);
+
+ if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
+ {
+ if (lproto == p)
+ fnd = lproto;
+
+ else if (PROTOCOL_LIST (p))
+ fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
+ }
+
+ if (fnd)
+ return fnd;
+ }
+ }
+ else
+ ; /* An identifier...if we could not find a protocol. */
+
+ return 0;
+}
+
+/* Return 1 if LHS and RHS are compatible types for assignment
+ or various other operations. Return 0 if they are incompatible,
+ and return -1 if we choose to not decide. When the operation
+ is REFLEXIVE, check for compatibility in either direction. */
+
+int
+objc_comptypes (lhs, rhs, reflexive)
+ tree lhs;
+ tree rhs;
+ int reflexive;
+{
+ /* New clause for protocols. */
+
+ if (TREE_CODE (lhs) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
+ && TREE_CODE (rhs) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
+ {
+ int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
+ int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
+
+ if (lhs_is_proto)
+ {
+ tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
+ tree rproto, rproto_list;
+ tree p;
+
+ if (rhs_is_proto)
+ {
+ rproto_list = TYPE_PROTOCOL_LIST (rhs);
+
+ /* Make sure the protocol is supported by the object
+ on the rhs. */
+ for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
+ {
+ p = TREE_VALUE (lproto);
+ rproto = lookup_protocol_in_reflist (rproto_list, p);
+
+ if (!rproto)
+ warning ("object does not conform to the `%s' protocol",
+ IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
+ }
+ }
+ else if (TYPED_OBJECT (TREE_TYPE (rhs)))
+ {
+ tree rname = TYPE_NAME (TREE_TYPE (rhs));
+ tree rinter;
+
+ /* Make sure the protocol is supported by the object
+ on the rhs. */
+ for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
+ {
+ p = TREE_VALUE (lproto);
+ rproto = 0;
+ rinter = lookup_interface (rname);
+
+ while (rinter && !rproto)
+ {
+ tree cat;
+
+ rproto_list = CLASS_PROTOCOL_LIST (rinter);
+ rproto = lookup_protocol_in_reflist (rproto_list, p);
+
+ /* Check for protocols adopted by categories. */
+ cat = CLASS_CATEGORY_LIST (rinter);
+ while (cat && !rproto)
+ {
+ rproto_list = CLASS_PROTOCOL_LIST (cat);
+ rproto = lookup_protocol_in_reflist (rproto_list, p);
+
+ cat = CLASS_CATEGORY_LIST (cat);
+ }
+
+ rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
+ }
+
+ if (!rproto)
+ warning ("class `%s' does not implement the `%s' protocol",
+ IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
+ IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
+ }
+ }
+
+ /* May change...based on whether there was any mismatch */
+ return 1;
+ }
+ else if (rhs_is_proto)
+ /* Lhs is not a protocol...warn if it is statically typed */
+ return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
+
+ else
+ /* Defer to comptypes .*/
+ return -1;
+ }
+
+ else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
+ ; /* Fall thru. This is the case we have been handling all along */
+ else
+ /* Defer to comptypes. */
+ return -1;
+
+ /* `id' = `<class> *', `<class> *' = `id' */
+
+ if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
+ || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
+ return 1;
+
+ /* `id' = `Class', `Class' = `id' */
+
+ else if ((TYPE_NAME (lhs) == objc_object_id
+ && TYPE_NAME (rhs) == objc_class_id)
+ || (TYPE_NAME (lhs) == objc_class_id
+ && TYPE_NAME (rhs) == objc_object_id))
+ return 1;
+
+ /* `<class> *' = `<class> *' */
+
+ else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
+ {
+ tree lname = TYPE_NAME (lhs);
+ tree rname = TYPE_NAME (rhs);
+ tree inter;
+
+ if (lname == rname)
+ return 1;
+
+ /* If the left hand side is a super class of the right hand side,
+ allow it. */
+ for (inter = lookup_interface (rname); inter;
+ inter = lookup_interface (CLASS_SUPER_NAME (inter)))
+ if (lname == CLASS_SUPER_NAME (inter))
+ return 1;
+
+ /* Allow the reverse when reflexive. */
+ if (reflexive)
+ for (inter = lookup_interface (lname); inter;
+ inter = lookup_interface (CLASS_SUPER_NAME (inter)))
+ if (rname == CLASS_SUPER_NAME (inter))
+ return 1;
+
+ return 0;
+ }
+ else
+ /* Defer to comptypes. */
+ return -1;
+}
+
+/* Called from c-decl.c before all calls to rest_of_decl_compilation. */
+
+void
+objc_check_decl (decl)
+ tree decl;
+{
+ tree type = TREE_TYPE (decl);
+
+ if (TREE_CODE (type) == RECORD_TYPE
+ && TREE_STATIC_TEMPLATE (type)
+ && type != constant_string_type)
+ {
+ error_with_decl (decl, "`%s' cannot be statically allocated");
+ fatal ("statically allocated objects not supported");
+ }
+}
+
+void
+maybe_objc_check_decl (decl)
+ tree decl;
+{
+ if (doing_objc_thang)
+ objc_check_decl (decl);
+}
+
+/* Implement static typing. At this point, we know we have an interface. */
+
+tree
+get_static_reference (interface, protocols)
+ tree interface;
+ tree protocols;
+{
+ tree type = xref_tag (RECORD_TYPE, interface);
+
+ if (protocols)
+ {
+ tree t, m = TYPE_MAIN_VARIANT (type);
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+ t = copy_node (type);
+ TYPE_BINFO (t) = make_tree_vec (2);
+ pop_obstacks ();
+
+ /* Add this type to the chain of variants of TYPE. */
+ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
+ TYPE_NEXT_VARIANT (m) = t;
+
+ /* Look up protocols and install in lang specific list. */
+ TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
+
+ /* This forces a new pointer type to be created later
+ (in build_pointer_type)...so that the new template
+ we just created will actually be used...what a hack! */
+ if (TYPE_POINTER_TO (t))
+ TYPE_POINTER_TO (t) = 0;
+
+ type = t;
+ }
+
+ return type;
+}
+
+tree
+get_object_reference (protocols)
+ tree protocols;
+{
+ tree type_decl = lookup_name (objc_id_id);
+ tree type;
+
+ if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
+ {
+ type = TREE_TYPE (type_decl);
+ if (TYPE_MAIN_VARIANT (type) != id_type)
+ warning ("Unexpected type for `id' (%s)",
+ gen_declaration (type, errbuf));
+ }
+ else
+ fatal ("Undefined type `id', please import <objc/objc.h>");
+
+ /* This clause creates a new pointer type that is qualified with
+ the protocol specification...this info is used later to do more
+ elaborate type checking. */
+
+ if (protocols)
+ {
+ tree t, m = TYPE_MAIN_VARIANT (type);
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+ t = copy_node (type);
+ TYPE_BINFO (t) = make_tree_vec (2);
+ pop_obstacks ();
+
+ /* Add this type to the chain of variants of TYPE. */
+ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
+ TYPE_NEXT_VARIANT (m) = t;
+
+ /* Look up protocols...and install in lang specific list */
+ TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
+
+ /* This forces a new pointer type to be created later
+ (in build_pointer_type)...so that the new template
+ we just created will actually be used...what a hack! */
+ if (TYPE_POINTER_TO (t))
+ TYPE_POINTER_TO (t) = NULL;
+
+ type = t;
+ }
+ return type;
+}
+
+static tree
+lookup_and_install_protocols (protocols)
+ tree protocols;
+{
+ tree proto;
+ tree prev = NULL;
+ tree return_value = protocols;
+
+ for (proto = protocols; proto; proto = TREE_CHAIN (proto))
+ {
+ tree ident = TREE_VALUE (proto);
+ tree p = lookup_protocol (ident);
+
+ if (!p)
+ {
+ error ("Cannot find protocol declaration for `%s'",
+ IDENTIFIER_POINTER (ident));
+ if (prev)
+ TREE_CHAIN (prev) = TREE_CHAIN (proto);
+ else
+ return_value = TREE_CHAIN (proto);
+ }
+ else
+ {
+ /* Replace identifier with actual protocol node. */
+ TREE_VALUE (proto) = p;
+ prev = proto;
+ }
+ }
+
+ return return_value;
+}
+
+/* Create and push a decl for a built-in external variable or field NAME.
+ CODE says which.
+ TYPE is its data type. */
+
+static tree
+create_builtin_decl (code, type, name)
+ enum tree_code code;
+ tree type;
+ char *name;
+{
+ tree decl = build_decl (code, get_identifier (name), type);
+
+ if (code == VAR_DECL)
+ {
+ TREE_STATIC (decl) = 1;
+ make_decl_rtl (decl, 0, 1);
+ pushdecl (decl);
+ }
+
+ DECL_ARTIFICIAL (decl) = 1;
+ return decl;
+}
+
+/* Purpose: "play" parser, creating/installing representations
+ of the declarations that are required by Objective-C.
+
+ Model:
+
+ type_spec--------->sc_spec
+ (tree_list) (tree_list)
+ | |
+ | |
+ identifier_node identifier_node */
+
+static void
+synth_module_prologue ()
+{
+ tree temp_type;
+ tree super_p;
+
+ /* Defined in `objc.h' */
+ objc_object_id = get_identifier (TAG_OBJECT);
+
+ objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
+
+ id_type = build_pointer_type (objc_object_reference);
+
+ objc_id_id = get_identifier (TYPE_ID);
+ objc_class_id = get_identifier (TAG_CLASS);
+
+ objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
+ protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
+ get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
+
+ /* Declare type of selector-objects that represent an operation name. */
+
+#ifdef OBJC_INT_SELECTORS
+ /* `unsigned int' */
+ selector_type = unsigned_type_node;
+#else
+ /* `struct objc_selector *' */
+ selector_type
+ = build_pointer_type (xref_tag (RECORD_TYPE,
+ get_identifier (TAG_SELECTOR)));
+#endif /* not OBJC_INT_SELECTORS */
+
+ /* Forward declare type, or else the prototype for msgSendSuper will
+ complain. */
+
+ super_p = build_pointer_type (xref_tag (RECORD_TYPE,
+ get_identifier (TAG_SUPER)));
+
+
+ /* id objc_msgSend (id, SEL, ...); */
+
+ temp_type
+ = build_function_type (id_type,
+ tree_cons (NULL_TREE, id_type,
+ tree_cons (NULL_TREE, selector_type,
+ NULL_TREE)));
+
+ if (! flag_next_runtime)
+ {
+ umsg_decl = build_decl (FUNCTION_DECL,
+ get_identifier (TAG_MSGSEND), temp_type);
+ DECL_EXTERNAL (umsg_decl) = 1;
+ TREE_PUBLIC (umsg_decl) = 1;
+ DECL_INLINE (umsg_decl) = 1;
+ DECL_ARTIFICIAL (umsg_decl) = 1;
+
+ if (flag_traditional && TAG_MSGSEND[0] != '_')
+ DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
+
+ make_decl_rtl (umsg_decl, NULL_PTR, 1);
+ pushdecl (umsg_decl);
+ }
+ else
+ umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0);
+
+ /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
+
+ temp_type
+ = build_function_type (id_type,
+ tree_cons (NULL_TREE, super_p,
+ tree_cons (NULL_TREE, selector_type,
+ NULL_TREE)));
+
+ umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
+ temp_type, NOT_BUILT_IN, 0);
+
+ /* id objc_getClass (const char *); */
+
+ temp_type = build_function_type (id_type,
+ tree_cons (NULL_TREE,
+ const_string_type_node,
+ tree_cons (NULL_TREE, void_type_node,
+ NULL_TREE)));
+
+ objc_get_class_decl
+ = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0);
+
+ /* id objc_getMetaClass (const char *); */
+
+ objc_get_meta_class_decl
+ = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0);
+
+ /* static SEL _OBJC_SELECTOR_TABLE[]; */
+
+ if (! flag_next_runtime)
+ {
+ if (flag_typed_selectors)
+ {
+ /* Suppress outputting debug symbols, because
+ dbxout_init hasn'r been called yet. */
+ enum debug_info_type save_write_symbols = write_symbols;
+ write_symbols = NO_DEBUG;
+
+ build_selector_template ();
+ temp_type = build_array_type (objc_selector_template, NULL_TREE);
+
+ write_symbols = save_write_symbols;
+ }
+ else
+ temp_type = build_array_type (selector_type, NULL_TREE);
+
+ layout_type (temp_type);
+ UOBJC_SELECTOR_TABLE_decl
+ = create_builtin_decl (VAR_DECL, temp_type,
+ "_OBJC_SELECTOR_TABLE");
+
+ /* Avoid warning when not sending messages. */
+ TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
+ }
+
+ generate_forward_declaration_to_string_table ();
+
+ /* Forward declare constant_string_id and constant_string_type. */
+ constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME);
+ constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
+}
+
+/* Custom build_string which sets TREE_TYPE! */
+
+static tree
+my_build_string (len, str)
+ int len;
+ char *str;
+{
+ int wide_flag = 0;
+ tree a_string = build_string (len, str);
+
+ /* Some code from combine_strings, which is local to c-parse.y. */
+ if (TREE_TYPE (a_string) == int_array_type_node)
+ wide_flag = 1;
+
+ TREE_TYPE (a_string)
+ = build_array_type (wide_flag ? integer_type_node : char_type_node,
+ build_index_type (build_int_2 (len - 1, 0)));
+
+ TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
+ TREE_STATIC (a_string) = 1;
+
+ return a_string;
+}
+
+/* Return a newly constructed OBJC_STRING_CST node whose value is
+ the LEN characters at STR.
+ The TREE_TYPE is not initialized. */
+
+tree
+build_objc_string (len, str)
+ int len;
+ char *str;
+{
+ tree s = build_string (len, str);
+
+ TREE_SET_CODE (s, OBJC_STRING_CST);
+ return s;
+}
+
+/* Given a chain of OBJC_STRING_CST's, build a static instance of
+ NXConstanString which points at the concatenation of those strings.
+ We place the string object in the __string_objects section of the
+ __OBJC segment. The Objective-C runtime will initialize the isa
+ pointers of the string objects to point at the NXConstandString class
+ object. */
+
+tree
+build_objc_string_object (strings)
+ tree strings;
+{
+ tree string, initlist, constructor;
+ int length;
+
+ if (!doing_objc_thang)
+ objc_fatal ();
+
+ if (lookup_interface (constant_string_id) == NULL_TREE)
+ {
+ error ("Cannot find interface declaration for `%s'",
+ IDENTIFIER_POINTER (constant_string_id));
+ return error_mark_node;
+ }
+
+ add_class_reference (constant_string_id);
+
+ /* Combine_strings will work for OBJC_STRING_CST's too. */
+ string = combine_strings (strings);
+ TREE_SET_CODE (string, STRING_CST);
+ length = TREE_STRING_LENGTH (string) - 1;
+
+ if (! flag_next_runtime)
+ {
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+ if (! TREE_PERMANENT (strings))
+ string = my_build_string (length + 1,
+ TREE_STRING_POINTER (string));
+ }
+
+ /* & ((NXConstantString) {0, string, length}) */
+
+ initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
+ initlist
+ = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
+ initlist);
+ initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
+ constructor = build_constructor (constant_string_type, nreverse (initlist));
+
+ if (!flag_next_runtime)
+ {
+ constructor
+ = objc_add_static_instance (constructor, constant_string_type);
+ pop_obstacks ();
+ }
+
+ return (build_unary_op (ADDR_EXPR, constructor, 1));
+}
+
+/* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
+
+static tree
+objc_add_static_instance (constructor, class_decl)
+ tree constructor, class_decl;
+{
+ static int num_static_inst;
+ tree *chain, decl, decl_spec, decl_expr;
+ char buf[256];
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ /* Find the list of static instances for the CLASS_DECL. Create one if
+ not found. */
+ for (chain = &objc_static_instances;
+ *chain && TREE_VALUE (*chain) != class_decl;
+ chain = &TREE_CHAIN (*chain));
+ if (!*chain)
+ {
+ *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
+ add_objc_string (TYPE_NAME (class_decl), class_names);
+ }
+
+ sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
+ decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
+ DECL_COMMON (decl) = 1;
+ TREE_STATIC (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ pushdecl_top_level (decl);
+ rest_of_decl_compilation (decl, 0, 1, 0);
+
+ /* Do this here so it gets output later instead of possibly
+ inside something else we are writing. */
+ DECL_INITIAL (decl) = constructor;
+
+ /* Add the DECL to the head of this CLASS' list. */
+ TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
+
+ pop_obstacks ();
+ return decl;
+}
+
+/* Build a static constant CONSTRUCTOR
+ with type TYPE and elements ELTS. */
+
+static tree
+build_constructor (type, elts)
+ tree type, elts;
+{
+ tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
+
+ TREE_CONSTANT (constructor) = 1;
+ TREE_STATIC (constructor) = 1;
+ TREE_READONLY (constructor) = 1;
+
+ return constructor;
+}
+
+/* Take care of defining and initializing _OBJC_SYMBOLS. */
+
+/* Predefine the following data type:
+
+ struct _objc_symtab
+ {
+ long sel_ref_cnt;
+ SEL *refs;
+ short cls_def_cnt;
+ short cat_def_cnt;
+ void *defs[cls_def_cnt + cat_def_cnt];
+ }; */
+
+static void
+build_objc_symtab_template ()
+{
+ tree field_decl, field_decl_chain, index;
+
+ objc_symtab_template
+ = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
+
+ /* long sel_ref_cnt; */
+
+ field_decl = create_builtin_decl (FIELD_DECL,
+ long_integer_type_node,
+ "sel_ref_cnt");
+ field_decl_chain = field_decl;
+
+ /* SEL *refs; */
+
+ field_decl = create_builtin_decl (FIELD_DECL,
+ build_pointer_type (selector_type),
+ "refs");
+ chainon (field_decl_chain, field_decl);
+
+ /* short cls_def_cnt; */
+
+ field_decl = create_builtin_decl (FIELD_DECL,
+ short_integer_type_node,
+ "cls_def_cnt");
+ chainon (field_decl_chain, field_decl);
+
+ /* short cat_def_cnt; */
+
+ field_decl = create_builtin_decl (FIELD_DECL,
+ short_integer_type_node,
+ "cat_def_cnt");
+ chainon (field_decl_chain, field_decl);
+
+ /* void *defs[cls_def_cnt + cat_def_cnt]; */
+
+ if (!flag_next_runtime)
+ index = build_index_type (build_int_2 (imp_count + cat_count, 0));
+ else
+ index = build_index_type (build_int_2 (imp_count + cat_count - 1,
+ imp_count == 0 && cat_count == 0
+ ? -1 : 0));
+ field_decl = create_builtin_decl (FIELD_DECL,
+ build_array_type (ptr_type_node, index),
+ "defs");
+ chainon (field_decl_chain, field_decl);
+
+ finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
+}
+
+/* Create the initial value for the `defs' field of _objc_symtab.
+ This is a CONSTRUCTOR. */
+
+static tree
+init_def_list (type)
+ tree type;
+{
+ tree expr, initlist = NULL_TREE;
+ struct imp_entry *impent;
+
+ if (imp_count)
+ for (impent = imp_list; impent; impent = impent->next)
+ {
+ if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
+ {
+ expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
+ }
+
+ if (cat_count)
+ for (impent = imp_list; impent; impent = impent->next)
+ {
+ if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
+ {
+ expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
+ }
+
+ if (!flag_next_runtime)
+ {
+ /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
+ tree expr;
+
+ if (static_instances_decl)
+ expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
+ else
+ expr = build_int_2 (0, 0);
+
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
+
+ return build_constructor (type, nreverse (initlist));
+}
+
+/* Construct the initial value for all of _objc_symtab. */
+
+static tree
+init_objc_symtab (type)
+ tree type;
+{
+ tree initlist;
+
+ /* sel_ref_cnt = { ..., 5, ... } */
+
+ initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
+
+ /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
+
+ if (flag_next_runtime || ! sel_ref_chain)
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+ else
+ initlist = tree_cons (NULL_TREE,
+ build_unary_op (ADDR_EXPR,
+ UOBJC_SELECTOR_TABLE_decl, 1),
+ initlist);
+
+ /* cls_def_cnt = { ..., 5, ... } */
+
+ initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
+
+ /* cat_def_cnt = { ..., 5, ... } */
+
+ initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
+
+ /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
+
+ if (imp_count || cat_count || static_instances_decl)
+ {
+
+ tree field = TYPE_FIELDS (type);
+ field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
+
+ initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
+ initlist);
+ }
+
+ return build_constructor (type, nreverse (initlist));
+}
+
+/* Push forward-declarations of all the categories
+ so that init_def_list can use them in a CONSTRUCTOR. */
+
+static void
+forward_declare_categories ()
+{
+ struct imp_entry *impent;
+ tree sav = implementation_context;
+
+ for (impent = imp_list; impent; impent = impent->next)
+ {
+ if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
+ {
+ /* Set an invisible arg to synth_id_with_class_suffix. */
+ implementation_context = impent->imp_context;
+ impent->class_decl
+ = create_builtin_decl (VAR_DECL, objc_category_template,
+ IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
+ }
+ }
+ implementation_context = sav;
+}
+
+/* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
+ and initialized appropriately. */
+
+static void
+generate_objc_symtab_decl ()
+{
+ tree sc_spec;
+
+ if (!objc_category_template)
+ build_category_template ();
+
+ /* forward declare categories */
+ if (cat_count)
+ forward_declare_categories ();
+
+ if (!objc_symtab_template)
+ build_objc_symtab_template ();
+
+ sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
+
+ UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
+ tree_cons (NULL_TREE,
+ objc_symtab_template, sc_spec),
+ 1,
+ NULL_TREE, NULL_TREE);
+
+ TREE_USED (UOBJC_SYMBOLS_decl) = 1;
+ DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
+ DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
+ finish_decl (UOBJC_SYMBOLS_decl,
+ init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
+ NULL_TREE);
+}
+
+static tree
+init_module_descriptor (type)
+ tree type;
+{
+ tree initlist, expr;
+
+ /* version = { 1, ... } */
+
+ expr = build_int_2 (OBJC_VERSION, 0);
+ initlist = build_tree_list (NULL_TREE, expr);
+
+ /* size = { ..., sizeof (struct objc_module), ... } */
+
+ expr = size_in_bytes (objc_module_template);
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+
+ /* name = { ..., "foo.m", ... } */
+
+ expr = add_objc_string (get_identifier (input_filename), class_names);
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+
+ /* symtab = { ..., _OBJC_SYMBOLS, ... } */
+
+ if (UOBJC_SYMBOLS_decl)
+ expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
+ else
+ expr = build_int_2 (0, 0);
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+
+ return build_constructor (type, nreverse (initlist));
+}
+
+/* Write out the data structures to describe Objective C classes defined.
+ If appropriate, compile and output a setup function to initialize them.
+ Return a string which is the name of a function to call to initialize
+ the Objective C data structures for this file (and perhaps for other files
+ also).
+
+ struct objc_module { ... } _OBJC_MODULE = { ... }; */
+
+static char *
+build_module_descriptor ()
+{
+ tree decl_specs, field_decl, field_decl_chain;
+
+ objc_module_template
+ = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
+
+ /* Long version; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
+ field_decl = get_identifier ("version");
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl_chain = field_decl;
+
+ /* long size; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
+ field_decl = get_identifier ("size");
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* char *name; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* struct objc_symtab *symtab; */
+
+ decl_specs = get_identifier (UTAG_SYMTAB);
+ decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
+
+ /* Create an instance of "objc_module". */
+
+ decl_specs = tree_cons (NULL_TREE, objc_module_template,
+ build_tree_list (NULL_TREE,
+ ridpointers[(int) RID_STATIC]));
+
+ UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
+ decl_specs, 1, NULL_TREE, NULL_TREE);
+
+ DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
+ DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
+ finish_decl (UOBJC_MODULES_decl,
+ init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
+ NULL_TREE);
+
+ /* Mark the decl to avoid "defined but not used" warning. */
+ DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
+
+ /* Generate a constructor call for the module descriptor.
+ This code was generated by reading the grammar rules
+ of c-parse.in; Therefore, it may not be the most efficient
+ way of generating the requisite code. */
+
+ if (flag_next_runtime)
+ return 0;
+
+ {
+ tree parms, function_decl, decelerator, void_list_node;
+ tree function_type;
+ extern tree get_file_function_name ();
+ tree init_function_name = get_file_function_name ('I');
+
+ /* Declare void __objc_execClass (void *); */
+
+ void_list_node = build_tree_list (NULL_TREE, void_type_node);
+ function_type
+ = build_function_type (void_type_node,
+ tree_cons (NULL_TREE, ptr_type_node,
+ void_list_node));
+ function_decl = build_decl (FUNCTION_DECL,
+ get_identifier (TAG_EXECCLASS),
+ function_type);
+ DECL_EXTERNAL (function_decl) = 1;
+ DECL_ARTIFICIAL (function_decl) = 1;
+ TREE_PUBLIC (function_decl) = 1;
+
+ pushdecl (function_decl);
+ rest_of_decl_compilation (function_decl, 0, 0, 0);
+
+ parms
+ = build_tree_list (NULL_TREE,
+ build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
+ decelerator = build_function_call (function_decl, parms);
+
+ /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
+
+ start_function (void_list_node,
+ build_parse_node (CALL_EXPR, init_function_name,
+ /* This has the format of the output
+ of get_parm_info. */
+ tree_cons (NULL_TREE, NULL_TREE,
+ void_list_node),
+ NULL_TREE),
+ NULL_TREE, NULL_TREE, 0);
+#if 0 /* This should be turned back on later
+ for the systems where collect is not needed. */
+ /* Make these functions nonglobal
+ so each file can use the same name. */
+ TREE_PUBLIC (current_function_decl) = 0;
+#endif
+ TREE_USED (current_function_decl) = 1;
+ store_parm_decls ();
+
+ assemble_external (function_decl);
+ c_expand_expr_stmt (decelerator);
+
+ TREE_PUBLIC (current_function_decl) = 1;
+
+ function_decl = current_function_decl;
+ finish_function (0);
+
+ /* Return the name of the constructor function. */
+ return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
+ }
+}
+
+/* extern const char _OBJC_STRINGS[]; */
+
+static void
+generate_forward_declaration_to_string_table ()
+{
+ tree sc_spec, decl_specs, expr_decl;
+
+ sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
+ decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
+
+ expr_decl
+ = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
+
+ UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
+}
+
+/* Return the DECL of the string IDENT in the SECTION. */
+
+static tree
+get_objc_string_decl (ident, section)
+ tree ident;
+ enum string_section section;
+{
+ tree chain, decl;
+
+ if (section == class_names)
+ chain = class_names_chain;
+ else if (section == meth_var_names)
+ chain = meth_var_names_chain;
+ else if (section == meth_var_types)
+ chain = meth_var_types_chain;
+
+ for (; chain != 0; chain = TREE_VALUE (chain))
+ if (TREE_VALUE (chain) == ident)
+ return (TREE_PURPOSE (chain));
+
+ abort ();
+ return NULL_TREE;
+}
+
+/* Output references to all statically allocated objects. Return the DECL
+ for the array built. */
+
+static void
+generate_static_references ()
+{
+ tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
+ tree class_name, class, decl, instance, idecl, initlist;
+ tree cl_chain, in_chain, type;
+ int num_inst, num_class;
+ char buf[256];
+
+ if (flag_next_runtime)
+ abort ();
+
+ for (cl_chain = objc_static_instances, num_class = 0;
+ cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
+ {
+ for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
+ in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
+
+ sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
+ ident = get_identifier (buf);
+
+ expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
+ decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
+ build_tree_list (NULL_TREE,
+ ridpointers[(int) RID_STATIC]));
+ decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
+ DECL_CONTEXT (decl) = 0;
+ DECL_ARTIFICIAL (decl) = 1;
+
+ /* Output {class_name, ...}. */
+ class = TREE_VALUE (cl_chain);
+ class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
+ initlist = build_tree_list (NULL_TREE,
+ build_unary_op (ADDR_EXPR, class_name, 1));
+
+ /* Output {..., instance, ...}. */
+ for (in_chain = TREE_PURPOSE (cl_chain);
+ in_chain; in_chain = TREE_CHAIN (in_chain))
+ {
+ expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
+
+ /* Output {..., NULL}. */
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+
+ expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
+ finish_decl (decl, expr, NULL_TREE);
+ TREE_USED (decl) = 1;
+
+ type = build_array_type (build_pointer_type (void_type_node), 0);
+ decl = build_decl (VAR_DECL, ident, type);
+ make_decl_rtl (decl, 0, 1);
+ TREE_USED (decl) = 1;
+ decls
+ = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
+ }
+
+ decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
+ ident = get_identifier ("_OBJC_STATIC_INSTANCES");
+ expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
+ decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
+ build_tree_list (NULL_TREE,
+ ridpointers[(int) RID_STATIC]));
+ static_instances_decl
+ = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
+ TREE_USED (static_instances_decl) = 1;
+ DECL_CONTEXT (static_instances_decl) = 0;
+ DECL_ARTIFICIAL (static_instances_decl) = 1;
+ end_temporary_allocation ();
+ expr = build_constructor (TREE_TYPE (static_instances_decl),
+ nreverse (decls));
+ finish_decl (static_instances_decl, expr, NULL_TREE);
+}
+
+/* Output all strings. */
+
+static void
+generate_strings ()
+{
+ tree sc_spec, decl_specs, expr_decl;
+ tree chain, string_expr;
+ tree string, decl;
+
+ for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
+ {
+ string = TREE_VALUE (chain);
+ decl = TREE_PURPOSE (chain);
+ sc_spec
+ = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+ decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
+ expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
+ decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
+ end_temporary_allocation ();
+ string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
+ IDENTIFIER_POINTER (string));
+ finish_decl (decl, string_expr, NULL_TREE);
+ }
+
+ for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
+ {
+ string = TREE_VALUE (chain);
+ decl = TREE_PURPOSE (chain);
+ sc_spec
+ = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+ decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
+ expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
+ decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
+ string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
+ IDENTIFIER_POINTER (string));
+ finish_decl (decl, string_expr, NULL_TREE);
+ }
+
+ for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
+ {
+ string = TREE_VALUE (chain);
+ decl = TREE_PURPOSE (chain);
+ sc_spec
+ = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+ decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
+ expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
+ decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
+ string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
+ IDENTIFIER_POINTER (string));
+ finish_decl (decl, string_expr, NULL_TREE);
+ }
+}
+
+static tree
+build_selector_reference_decl (name)
+ tree name;
+{
+ tree decl, ident;
+ char buf[256];
+ static int idx = 0;
+
+ sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ ident = get_identifier (buf);
+
+ decl = build_decl (VAR_DECL, ident, selector_type);
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ TREE_USED (decl) = 1;
+ TREE_READONLY (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_CONTEXT (decl) = 0;
+
+ make_decl_rtl (decl, 0, 1);
+ pushdecl_top_level (decl);
+
+ pop_obstacks ();
+
+ return decl;
+}
+
+/* Just a handy wrapper for add_objc_string. */
+
+static tree
+build_selector (ident)
+ tree ident;
+{
+ tree expr = add_objc_string (ident, meth_var_names);
+ if (flag_typed_selectors)
+ return expr;
+ else
+ return build_c_cast (selector_type, expr); /* cast! */
+}
+
+/* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
+ The cast stops the compiler from issuing the following message:
+ grok.m: warning: initialization of non-const * pointer from const *
+ grok.m: warning: initialization between incompatible pointer types. */
+
+static tree
+build_msg_pool_reference (offset)
+ int offset;
+{
+ tree expr = build_int_2 (offset, 0);
+ tree cast;
+
+ expr = build_array_ref (UOBJC_STRINGS_decl, expr);
+ expr = build_unary_op (ADDR_EXPR, expr, 0);
+
+ cast = build_tree_list (build_tree_list (NULL_TREE,
+ ridpointers[(int) RID_CHAR]),
+ build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
+ TREE_TYPE (expr) = groktypename (cast);
+ return expr;
+}
+
+static tree
+init_selector (offset)
+ int offset;
+{
+ tree expr = build_msg_pool_reference (offset);
+ TREE_TYPE (expr) = selector_type;
+ return expr;
+}
+
+static void
+build_selector_translation_table ()
+{
+ tree sc_spec, decl_specs;
+ tree chain, initlist = NULL_TREE;
+ int offset = 0;
+ tree decl, var_decl, name;
+
+ /* The corresponding pop_obstacks is in finish_decl,
+ called at the end of this function. */
+ if (! flag_next_runtime)
+ push_obstacks_nochange ();
+
+ for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
+ {
+ tree expr;
+
+ expr = build_selector (TREE_VALUE (chain));
+
+ if (flag_next_runtime)
+ {
+ name = DECL_NAME (TREE_PURPOSE (chain));
+
+ sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
+
+ /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
+ decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
+
+ var_decl = name;
+
+ /* The `decl' that is returned from start_decl is the one that we
+ forward declared in `build_selector_reference' */
+ decl = start_decl (var_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
+ }
+
+ /* add one for the '\0' character */
+ offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
+
+ if (flag_next_runtime)
+ finish_decl (decl, expr, NULL_TREE);
+ else
+ {
+ if (flag_typed_selectors)
+ {
+ tree eltlist = NULL_TREE;
+ tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
+ eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
+ eltlist = tree_cons (NULL_TREE, encoding, eltlist);
+ expr = build_constructor (objc_selector_template,
+ nreverse (eltlist));
+ }
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+
+ }
+ }
+
+ if (! flag_next_runtime)
+ {
+ /* Cause the variable and its initial value to be actually output. */
+ DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
+ TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
+ /* NULL terminate the list and fix the decl for output. */
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+ DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1;
+ initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
+ nreverse (initlist));
+ finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
+ current_function_decl = NULL_TREE;
+ }
+}
+
+static tree
+get_proto_encoding (proto)
+ tree proto;
+{
+ tree encoding;
+ if (proto)
+ {
+ tree tmp_decl;
+
+ if (! METHOD_ENCODING (proto))
+ {
+ tmp_decl = build_tmp_function_decl ();
+ hack_method_prototype (proto, tmp_decl);
+ encoding = encode_method_prototype (proto, tmp_decl);
+ METHOD_ENCODING (proto) = encoding;
+ }
+ else
+ encoding = METHOD_ENCODING (proto);
+
+ return add_objc_string (encoding, meth_var_types);
+ }
+ else
+ return build_int_2 (0, 0);
+}
+
+/* sel_ref_chain is a list whose "value" fields will be instances of
+ identifier_node that represent the selector. */
+
+static tree
+build_typed_selector_reference (ident, proto)
+ tree ident, proto;
+{
+ tree *chain = &sel_ref_chain;
+ tree expr;
+ int index = 0;
+
+ while (*chain)
+ {
+ if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
+ goto return_at_index;
+
+ index++;
+ chain = &TREE_CHAIN (*chain);
+ }
+
+ *chain = perm_tree_cons (proto, ident, NULL_TREE);
+
+ return_at_index:
+ expr = build_unary_op (ADDR_EXPR,
+ build_array_ref (UOBJC_SELECTOR_TABLE_decl,
+ build_int_2 (index, 0)),
+ 1);
+ return build_c_cast (selector_type, expr);
+}
+
+static tree
+build_selector_reference (ident)
+ tree ident;
+{
+ tree *chain = &sel_ref_chain;
+ tree expr;
+ int index = 0;
+
+ while (*chain)
+ {
+ if (TREE_VALUE (*chain) == ident)
+ return (flag_next_runtime
+ ? TREE_PURPOSE (*chain)
+ : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
+ build_int_2 (index, 0)));
+
+ index++;
+ chain = &TREE_CHAIN (*chain);
+ }
+
+ expr = build_selector_reference_decl (ident);
+
+ *chain = perm_tree_cons (expr, ident, NULL_TREE);
+
+ return (flag_next_runtime
+ ? expr
+ : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
+ build_int_2 (index, 0)));
+}
+
+static tree
+build_class_reference_decl (name)
+ tree name;
+{
+ tree decl, ident;
+ char buf[256];
+ static int idx = 0;
+
+ sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ ident = get_identifier (buf);
+
+ decl = build_decl (VAR_DECL, ident, objc_class_type);
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ TREE_USED (decl) = 1;
+ TREE_READONLY (decl) = 1;
+ DECL_CONTEXT (decl) = 0;
+ DECL_ARTIFICIAL (decl) = 1;
+
+ make_decl_rtl (decl, 0, 1);
+ pushdecl_top_level (decl);
+
+ pop_obstacks ();
+
+ return decl;
+}
+
+/* Create a class reference, but don't create a variable to reference
+ it. */
+
+static void
+add_class_reference (ident)
+ tree ident;
+{
+ tree chain;
+
+ if ((chain = cls_ref_chain))
+ {
+ tree tail;
+ do
+ {
+ if (ident == TREE_VALUE (chain))
+ return;
+
+ tail = chain;
+ chain = TREE_CHAIN (chain);
+ }
+ while (chain);
+
+ /* Append to the end of the list */
+ TREE_CHAIN (tail) = perm_tree_cons (NULL_TREE, ident, NULL_TREE);
+ }
+ else
+ cls_ref_chain = perm_tree_cons (NULL_TREE, ident, NULL_TREE);
+}
+
+/* Get a class reference, creating it if necessary. Also create the
+ reference variable. */
+
+tree
+get_class_reference (ident)
+ tree ident;
+{
+ if (flag_next_runtime)
+ {
+ tree *chain;
+ tree decl;
+
+ for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
+ if (TREE_VALUE (*chain) == ident)
+ {
+ if (! TREE_PURPOSE (*chain))
+ TREE_PURPOSE (*chain) = build_class_reference_decl (ident);
+
+ return TREE_PURPOSE (*chain);
+ }
+
+ decl = build_class_reference_decl (ident);
+ *chain = perm_tree_cons (decl, ident, NULL_TREE);
+ return decl;
+ }
+ else
+ {
+ tree params;
+
+ add_class_reference (ident);
+
+ params = build_tree_list (NULL_TREE,
+ my_build_string (IDENTIFIER_LENGTH (ident) + 1,
+ IDENTIFIER_POINTER (ident)));
+
+ assemble_external (objc_get_class_decl);
+ return build_function_call (objc_get_class_decl, params);
+ }
+}
+
+/* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
+ of identifier_node that represent the selector. It returns the
+ offset of the selector from the beginning of the _OBJC_STRINGS
+ pool. This offset is typically used by init_selector during code
+ generation.
+
+ For each string section we have a chain which maps identifier nodes
+ to decls for the strings. */
+
+static tree
+add_objc_string (ident, section)
+ tree ident;
+ enum string_section section;
+{
+ tree *chain, decl;
+
+ if (section == class_names)
+ chain = &class_names_chain;
+ else if (section == meth_var_names)
+ chain = &meth_var_names_chain;
+ else if (section == meth_var_types)
+ chain = &meth_var_types_chain;
+
+ while (*chain)
+ {
+ if (TREE_VALUE (*chain) == ident)
+ return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
+
+ chain = &TREE_CHAIN (*chain);
+ }
+
+ decl = build_objc_string_decl (ident, section);
+
+ *chain = perm_tree_cons (decl, ident, NULL_TREE);
+
+ return build_unary_op (ADDR_EXPR, decl, 1);
+}
+
+static tree
+build_objc_string_decl (name, section)
+ tree name;
+ enum string_section section;
+{
+ tree decl, ident;
+ char buf[256];
+ static int class_names_idx = 0;
+ static int meth_var_names_idx = 0;
+ static int meth_var_types_idx = 0;
+
+ if (section == class_names)
+ sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
+ else if (section == meth_var_names)
+ sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
+ else if (section == meth_var_types)
+ sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+ ident = get_identifier (buf);
+
+ decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ TREE_USED (decl) = 1;
+ TREE_READONLY (decl) = 1;
+ TREE_CONSTANT (decl) = 1;
+ DECL_CONTEXT (decl) = 0;
+ DECL_ARTIFICIAL (decl) = 1;
+
+ make_decl_rtl (decl, 0, 1);
+ pushdecl_top_level (decl);
+
+ pop_obstacks ();
+
+ return decl;
+}
+
+
+void
+objc_declare_alias (alias_ident, class_ident)
+ tree alias_ident;
+ tree class_ident;
+{
+ if (!doing_objc_thang)
+ objc_fatal ();
+
+ if (is_class_name (class_ident) != class_ident)
+ warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
+ else if (is_class_name (alias_ident))
+ warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
+ else
+ alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
+}
+
+void
+objc_declare_class (ident_list)
+ tree ident_list;
+{
+ tree list;
+
+ if (!doing_objc_thang)
+ objc_fatal ();
+
+ for (list = ident_list; list; list = TREE_CHAIN (list))
+ {
+ tree ident = TREE_VALUE (list);
+ tree decl;
+
+ if ((decl = lookup_name (ident)))
+ {
+ error ("`%s' redeclared as different kind of symbol",
+ IDENTIFIER_POINTER (ident));
+ error_with_decl (decl, "previous declaration of `%s'");
+ }
+
+ if (! is_class_name (ident))
+ {
+ tree record = xref_tag (RECORD_TYPE, ident);
+ TREE_STATIC_TEMPLATE (record) = 1;
+ class_chain = tree_cons (NULL_TREE, ident, class_chain);
+ }
+ }
+}
+
+tree
+is_class_name (ident)
+ tree ident;
+{
+ tree chain;
+
+ if (lookup_interface (ident))
+ return ident;
+
+ for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
+ {
+ if (ident == TREE_VALUE (chain))
+ return ident;
+ }
+
+ for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
+ {
+ if (ident == TREE_VALUE (chain))
+ return TREE_PURPOSE (chain);
+ }
+
+ return 0;
+}
+
+tree
+lookup_interface (ident)
+ tree ident;
+{
+ tree chain;
+
+ for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
+ {
+ if (ident == CLASS_NAME (chain))
+ return chain;
+ }
+ return NULL_TREE;
+}
+
+static tree
+objc_copy_list (list, head)
+ tree list;
+ tree *head;
+{
+ tree newlist = NULL_TREE, tail = NULL_TREE;
+
+ while (list)
+ {
+ tail = copy_node (list);
+
+ /* The following statement fixes a bug when inheriting instance
+ variables that are declared to be bitfields. finish_struct
+ expects to find the width of the bitfield in DECL_INITIAL,
+ which it nulls out after processing the decl of the super
+ class...rather than change the way finish_struct works (which
+ is risky), I create the situation it expects...s.naroff
+ (7/23/89). */
+
+ if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
+ DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);
+
+ newlist = chainon (newlist, tail);
+ list = TREE_CHAIN (list);
+ }
+
+ *head = newlist;
+ return tail;
+}
+
+/* Used by: build_private_template, get_class_ivars, and
+ continue_class. COPY is 1 when called from @defs. In this case
+ copy all fields. Otherwise don't copy leaf ivars since we rely on
+ them being side-effected exactly once by finish_struct. */
+
+static tree
+build_ivar_chain (interface, copy)
+ tree interface;
+ int copy;
+{
+ tree my_name, super_name, ivar_chain;
+
+ my_name = CLASS_NAME (interface);
+ super_name = CLASS_SUPER_NAME (interface);
+
+ /* Possibly copy leaf ivars. */
+ if (copy)
+ objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
+ else
+ ivar_chain = CLASS_IVARS (interface);
+
+ while (super_name)
+ {
+ tree op1;
+ tree super_interface = lookup_interface (super_name);
+
+ if (!super_interface)
+ {
+ /* fatal did not work with 2 args...should fix */
+ error ("Cannot find interface declaration for `%s', superclass of `%s'",
+ IDENTIFIER_POINTER (super_name),
+ IDENTIFIER_POINTER (my_name));
+ exit (FATAL_EXIT_CODE);
+ }
+
+ if (super_interface == interface)
+ {
+ fatal ("Circular inheritance in interface declaration for `%s'",
+ IDENTIFIER_POINTER (super_name));
+ }
+
+ interface = super_interface;
+ my_name = CLASS_NAME (interface);
+ super_name = CLASS_SUPER_NAME (interface);
+
+ op1 = CLASS_IVARS (interface);
+ if (op1)
+ {
+ tree head, tail = objc_copy_list (op1, &head);
+
+ /* Prepend super class ivars...make a copy of the list, we
+ do not want to alter the original. */
+ TREE_CHAIN (tail) = ivar_chain;
+ ivar_chain = head;
+ }
+ }
+ return ivar_chain;
+}
+
+/* struct <classname> {
+ struct objc_class *isa;
+ ...
+ }; */
+
+static tree
+build_private_template (class)
+ tree class;
+{
+ tree ivar_context;
+
+ if (CLASS_STATIC_TEMPLATE (class))
+ {
+ uprivate_record = CLASS_STATIC_TEMPLATE (class);
+ ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
+ }
+ else
+ {
+ uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
+
+ ivar_context = build_ivar_chain (class, 0);
+
+ finish_struct (uprivate_record, ivar_context, NULL_TREE);
+
+ CLASS_STATIC_TEMPLATE (class) = uprivate_record;
+
+ /* mark this record as class template - for class type checking */
+ TREE_STATIC_TEMPLATE (uprivate_record) = 1;
+ }
+
+ instance_type
+ = groktypename (build_tree_list (build_tree_list (NULL_TREE,
+ uprivate_record),
+ build1 (INDIRECT_REF, NULL_TREE,
+ NULL_TREE)));
+
+ return ivar_context;
+}
+
+/* Begin code generation for protocols... */
+
+/* struct objc_protocol {
+ char *protocol_name;
+ struct objc_protocol **protocol_list;
+ struct objc_method_desc *instance_methods;
+ struct objc_method_desc *class_methods;
+ }; */
+
+static tree
+build_protocol_template ()
+{
+ tree decl_specs, field_decl, field_decl_chain;
+ tree template;
+
+ template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
+
+ /* struct objc_class *isa; */
+
+ decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_CLASS)));
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl_chain = field_decl;
+
+ /* char *protocol_name; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* struct objc_protocol **protocol_list; */
+
+ decl_specs = build_tree_list (NULL_TREE, template);
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* struct objc_method_list *instance_methods; */
+
+ decl_specs
+ = build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* struct objc_method_list *class_methods; */
+
+ decl_specs
+ = build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ return finish_struct (template, field_decl_chain, NULL_TREE);
+}
+
+static tree
+build_descriptor_table_initializer (type, entries)
+ tree type;
+ tree entries;
+{
+ tree initlist = NULL_TREE;
+
+ do
+ {
+ tree eltlist = NULL_TREE;
+
+ eltlist
+ = tree_cons (NULL_TREE,
+ build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
+ eltlist
+ = tree_cons (NULL_TREE,
+ add_objc_string (METHOD_ENCODING (entries),
+ meth_var_types),
+ eltlist);
+
+ initlist
+ = tree_cons (NULL_TREE,
+ build_constructor (type, nreverse (eltlist)), initlist);
+
+ entries = TREE_CHAIN (entries);
+ }
+ while (entries);
+
+ return build_constructor (build_array_type (type, 0), nreverse (initlist));
+}
+
+/* struct objc_method_prototype_list {
+ int count;
+ struct objc_method_prototype {
+ SEL name;
+ char *types;
+ } list[1];
+ }; */
+
+static tree
+build_method_prototype_list_template (list_type, size)
+ tree list_type;
+ int size;
+{
+ tree objc_ivar_list_record;
+ tree decl_specs, field_decl, field_decl_chain;
+
+ /* Generate an unnamed struct definition. */
+
+ objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
+
+ /* int method_count; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
+ field_decl = get_identifier ("method_count");
+
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl_chain = field_decl;
+
+ /* struct objc_method method_list[]; */
+
+ decl_specs = build_tree_list (NULL_TREE, list_type);
+ field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
+ build_int_2 (size, 0));
+
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
+
+ return objc_ivar_list_record;
+}
+
+static tree
+build_method_prototype_template ()
+{
+ tree proto_record;
+ tree decl_specs, field_decl, field_decl_chain;
+
+ proto_record
+ = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
+
+#ifdef OBJC_INT_SELECTORS
+ /* unsigned int _cmd; */
+ decl_specs
+ = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], NULL_TREE);
+ decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
+ field_decl = get_identifier ("_cmd");
+#else /* OBJC_INT_SELECTORS */
+ /* struct objc_selector *_cmd; */
+ decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
+ get_identifier (TAG_SELECTOR)), NULL_TREE);
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
+#endif /* OBJC_INT_SELECTORS */
+
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl_chain = field_decl;
+
+ decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ finish_struct (proto_record, field_decl_chain, NULL_TREE);
+
+ return proto_record;
+}
+
+/* True if last call to forwarding_offset yielded a register offset. */
+static int offset_is_register;
+
+static int
+forwarding_offset (parm)
+ tree parm;
+{
+ int offset_in_bytes;
+
+ if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
+ {
+ rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
+
+ /* ??? Here we assume that the parm address is indexed
+ off the frame pointer or arg pointer.
+ If that is not true, we produce meaningless results,
+ but do not crash. */
+ if (GET_CODE (addr) == PLUS
+ && GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ offset_in_bytes = INTVAL (XEXP (addr, 1));
+ else
+ offset_in_bytes = 0;
+
+ offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
+ offset_is_register = 0;
+ }
+ else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
+ {
+ int regno = REGNO (DECL_INCOMING_RTL (parm));
+ offset_in_bytes = apply_args_register_offset (regno);
+ offset_is_register = 1;
+ }
+ else
+ return 0;
+
+ /* This is the case where the parm is passed as an int or double
+ and it is converted to a char, short or float and stored back
+ in the parmlist. In this case, describe the parm
+ with the variable's declared type, and adjust the address
+ if the least significant bytes (which we are using) are not
+ the first ones. */
+ if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
+ offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
+ - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
+
+ return offset_in_bytes;
+}
+
+static tree
+encode_method_prototype (method_decl, func_decl)
+ tree method_decl;
+ tree func_decl;
+{
+ tree parms;
+ int stack_size, i;
+ tree user_args;
+ int max_parm_end = 0;
+ char buf[40];
+ tree result;
+
+ /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
+ encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
+
+ /* C type. */
+ encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
+ obstack_object_size (&util_obstack),
+ OBJC_ENCODE_INLINE_DEFS);
+
+ /* Stack size. */
+ for (parms = DECL_ARGUMENTS (func_decl); parms;
+ parms = TREE_CHAIN (parms))
+ {
+ int parm_end = (forwarding_offset (parms)
+ + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
+ / BITS_PER_UNIT));
+
+ if (!offset_is_register && max_parm_end < parm_end)
+ max_parm_end = parm_end;
+ }
+
+ stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
+
+ sprintf (buf, "%d", stack_size);
+ obstack_grow (&util_obstack, buf, strlen (buf));
+
+ user_args = METHOD_SEL_ARGS (method_decl);
+
+ /* Argument types. */
+ for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
+ parms = TREE_CHAIN (parms), i++)
+ {
+ /* Process argument qualifiers for user supplied arguments. */
+ if (i > 1)
+ {
+ encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
+ user_args = TREE_CHAIN (user_args);
+ }
+
+ /* Type. */
+ encode_type (TREE_TYPE (parms),
+ obstack_object_size (&util_obstack),
+ OBJC_ENCODE_INLINE_DEFS);
+
+ /* Compute offset. */
+ sprintf (buf, "%d", forwarding_offset (parms));
+
+ /* Indicate register. */
+ if (offset_is_register)
+ obstack_1grow (&util_obstack, '+');
+
+ obstack_grow (&util_obstack, buf, strlen (buf));
+ }
+
+ obstack_1grow (&util_obstack, '\0');
+ result = get_identifier (obstack_finish (&util_obstack));
+ obstack_free (&util_obstack, util_firstobj);
+ return result;
+}
+
+static tree
+generate_descriptor_table (type, name, size, list, proto)
+ tree type;
+ char *name;
+ int size;
+ tree list;
+ tree proto;
+{
+ tree sc_spec, decl_specs, decl, initlist;
+
+ sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+ decl_specs = tree_cons (NULL_TREE, type, sc_spec);
+
+ decl = start_decl (synth_id_with_class_suffix (name, proto),
+ decl_specs, 1, NULL_TREE, NULL_TREE);
+
+ initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
+ initlist = tree_cons (NULL_TREE, list, initlist);
+
+ finish_decl (decl, build_constructor (type, nreverse (initlist)),
+ NULL_TREE);
+
+ return decl;
+}
+
+static void
+generate_method_descriptors (protocol) /* generate_dispatch_tables */
+ tree protocol;
+{
+ static tree objc_method_prototype_template;
+ tree initlist, chain, method_list_template;
+ tree cast, variable_length_type;
+ int size;
+
+ if (!objc_method_prototype_template)
+ objc_method_prototype_template = build_method_prototype_template ();
+
+ cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
+ NULL_TREE);
+ variable_length_type = groktypename (cast);
+
+ chain = PROTOCOL_CLS_METHODS (protocol);
+ if (chain)
+ {
+ size = list_length (chain);
+
+ method_list_template
+ = build_method_prototype_list_template (objc_method_prototype_template,
+ size);
+
+ initlist
+ = build_descriptor_table_initializer (objc_method_prototype_template,
+ chain);
+
+ UOBJC_CLASS_METHODS_decl
+ = generate_descriptor_table (method_list_template,
+ "_OBJC_PROTOCOL_CLASS_METHODS",
+ size, initlist, protocol);
+ TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
+ }
+ else
+ UOBJC_CLASS_METHODS_decl = 0;
+
+ chain = PROTOCOL_NST_METHODS (protocol);
+ if (chain)
+ {
+ size = list_length (chain);
+
+ method_list_template
+ = build_method_prototype_list_template (objc_method_prototype_template,
+ size);
+ initlist
+ = build_descriptor_table_initializer (objc_method_prototype_template,
+ chain);
+
+ UOBJC_INSTANCE_METHODS_decl
+ = generate_descriptor_table (method_list_template,
+ "_OBJC_PROTOCOL_INSTANCE_METHODS",
+ size, initlist, protocol);
+ TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
+ }
+ else
+ UOBJC_INSTANCE_METHODS_decl = 0;
+}
+
+static tree
+build_tmp_function_decl ()
+{
+ tree decl_specs, expr_decl, parms;
+ static int xxx = 0;
+ char buffer[80];
+
+ /* struct objc_object *objc_xxx (id, SEL, ...); */
+ pushlevel (0);
+ decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
+ push_parm_decl (build_tree_list
+ (build_tree_list (decl_specs,
+ build1 (INDIRECT_REF, NULL_TREE,
+ NULL_TREE)),
+ build_tree_list (NULL_TREE, NULL_TREE)));
+
+ decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
+ get_identifier (TAG_SELECTOR)));
+ expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
+
+ push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
+ build_tree_list (NULL_TREE, NULL_TREE)));
+ parms = get_parm_info (0);
+ poplevel (0, 0, 0);
+
+ decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
+ sprintf (buffer, "__objc_tmp_%x", xxx++);
+ expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
+ expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
+
+ return define_decl (expr_decl, decl_specs);
+}
+
+static void
+hack_method_prototype (nst_methods, tmp_decl)
+ tree nst_methods;
+ tree tmp_decl;
+{
+ tree parms;
+ tree parm;
+
+ /* Hack to avoid problem with static typing of self arg. */
+ TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
+ start_method_def (nst_methods);
+ TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
+
+ if (METHOD_ADD_ARGS (nst_methods) == (tree) 1)
+ parms = get_parm_info (0); /* we have a `, ...' */
+ else
+ parms = get_parm_info (1); /* place a `void_at_end' */
+
+ poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
+
+ /* Usually called from store_parm_decls -> init_function_start. */
+
+ DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
+ current_function_decl = tmp_decl;
+
+ {
+ /* Code taken from start_function. */
+ tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
+ /* Promote the value to int before returning it. */
+ if (TREE_CODE (restype) == INTEGER_TYPE
+ && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
+ restype = integer_type_node;
+ DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
+ }
+
+ for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
+ DECL_CONTEXT (parm) = tmp_decl;
+
+ init_function_start (tmp_decl, "objc-act", 0);
+
+ /* Typically called from expand_function_start for function definitions. */
+ assign_parms (tmp_decl, 0);
+
+ /* install return type */
+ TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
+
+}
+
+static void
+generate_protocol_references (plist)
+ tree plist;
+{
+ tree lproto;
+
+ /* Forward declare protocols referenced. */
+ for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
+ {
+ tree proto = TREE_VALUE (lproto);
+
+ if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
+ && PROTOCOL_NAME (proto))
+ {
+ if (! PROTOCOL_FORWARD_DECL (proto))
+ build_protocol_reference (proto);
+
+ if (PROTOCOL_LIST (proto))
+ generate_protocol_references (PROTOCOL_LIST (proto));
+ }
+ }
+}
+
+static void
+generate_protocols ()
+{
+ tree p, tmp_decl, encoding;
+ tree sc_spec, decl_specs, decl;
+ tree initlist, protocol_name_expr, refs_decl, refs_expr;
+ tree cast_type2 = 0;
+
+ tmp_decl = build_tmp_function_decl ();
+
+ if (! objc_protocol_template)
+ objc_protocol_template = build_protocol_template ();
+
+ /* If a protocol was directly referenced, pull in indirect references. */
+ for (p = protocol_chain; p; p = TREE_CHAIN (p))
+ if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
+ generate_protocol_references (PROTOCOL_LIST (p));
+
+ for (p = protocol_chain; p; p = TREE_CHAIN (p))
+ {
+ tree nst_methods = PROTOCOL_NST_METHODS (p);
+ tree cls_methods = PROTOCOL_CLS_METHODS (p);
+
+ /* If protocol wasn't referenced, don't generate any code. */
+ if (! PROTOCOL_FORWARD_DECL (p))
+ continue;
+
+ /* Make sure we link in the Protocol class. */
+ add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
+
+ while (nst_methods)
+ {
+ if (! METHOD_ENCODING (nst_methods))
+ {
+ hack_method_prototype (nst_methods, tmp_decl);
+ encoding = encode_method_prototype (nst_methods, tmp_decl);
+ METHOD_ENCODING (nst_methods) = encoding;
+ }
+ nst_methods = TREE_CHAIN (nst_methods);
+ }
+
+ while (cls_methods)
+ {
+ if (! METHOD_ENCODING (cls_methods))
+ {
+ hack_method_prototype (cls_methods, tmp_decl);
+ encoding = encode_method_prototype (cls_methods, tmp_decl);
+ METHOD_ENCODING (cls_methods) = encoding;
+ }
+
+ cls_methods = TREE_CHAIN (cls_methods);
+ }
+ generate_method_descriptors (p);
+
+ if (PROTOCOL_LIST (p))
+ refs_decl = generate_protocol_list (p);
+ else
+ refs_decl = 0;
+
+ /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
+
+ sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
+ NULL_TREE);
+ decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
+
+ decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
+ decl_specs, 1, NULL_TREE, NULL_TREE);
+
+ protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
+
+ if (refs_decl)
+ {
+ if (!cast_type2)
+ cast_type2
+ = groktypename
+ (build_tree_list (build_tree_list (NULL_TREE,
+ objc_protocol_template),
+ build1 (INDIRECT_REF, NULL_TREE,
+ build1 (INDIRECT_REF, NULL_TREE,
+ NULL_TREE))));
+
+ refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
+ TREE_TYPE (refs_expr) = cast_type2;
+ }
+ else
+ refs_expr = build_int_2 (0, 0);
+
+ /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
+ by generate_method_descriptors, which is called above. */
+ initlist = build_protocol_initializer (TREE_TYPE (decl),
+ protocol_name_expr, refs_expr,
+ UOBJC_INSTANCE_METHODS_decl,
+ UOBJC_CLASS_METHODS_decl);
+ finish_decl (decl, initlist, NULL_TREE);
+
+ /* Mark the decl as used to avoid "defined but not used" warning. */
+ TREE_USED (decl) = 1;
+ }
+}
+
+static tree
+build_protocol_initializer (type, protocol_name, protocol_list,
+ instance_methods, class_methods)
+ tree type;
+ tree protocol_name;
+ tree protocol_list;
+ tree instance_methods;
+ tree class_methods;
+{
+ tree initlist = NULL_TREE, expr;
+ static tree cast_type = 0;
+
+ if (!cast_type)
+ cast_type
+ = groktypename
+ (build_tree_list
+ (build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_CLASS))),
+ build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
+
+ /* Filling the "isa" in with one allows the runtime system to
+ detect that the version change...should remove before final release. */
+
+ expr = build_int_2 (PROTOCOL_VERSION, 0);
+ TREE_TYPE (expr) = cast_type;
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ initlist = tree_cons (NULL_TREE, protocol_name, initlist);
+ initlist = tree_cons (NULL_TREE, protocol_list, initlist);
+
+ if (!instance_methods)
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+ else
+ {
+ expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
+
+ if (!class_methods)
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+ else
+ {
+ expr = build_unary_op (ADDR_EXPR, class_methods, 0);
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
+
+ return build_constructor (type, nreverse (initlist));
+}
+
+/* struct objc_category {
+ char *category_name;
+ char *class_name;
+ struct objc_method_list *instance_methods;
+ struct objc_method_list *class_methods;
+ struct objc_protocol_list *protocols;
+ }; */
+
+static void
+build_category_template ()
+{
+ tree decl_specs, field_decl, field_decl_chain;
+
+ objc_category_template = start_struct (RECORD_TYPE,
+ get_identifier (UTAG_CATEGORY));
+ /* char *category_name; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl_chain = field_decl;
+
+ /* char *class_name; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* struct objc_method_list *instance_methods; */
+
+ decl_specs = build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_METHOD_LIST)));
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* struct objc_method_list *class_methods; */
+
+ decl_specs = build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_METHOD_LIST)));
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* struct objc_protocol **protocol_list; */
+
+ decl_specs = build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_PROTOCOL)));
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
+}
+
+/* struct objc_selector {
+ void *sel_id;
+ char *sel_type;
+ }; */
+
+static void
+build_selector_template ()
+{
+
+ tree decl_specs, field_decl, field_decl_chain;
+
+ objc_selector_template
+ = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
+
+ /* void *sel_id; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl_chain = field_decl;
+
+ /* char *sel_type; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
+}
+
+/* struct objc_class {
+ struct objc_class *isa;
+ struct objc_class *super_class;
+ char *name;
+ long version;
+ long info;
+ long instance_size;
+ struct objc_ivar_list *ivars;
+ struct objc_method_list *methods;
+ if (flag_next_runtime)
+ struct objc_cache *cache;
+ else {
+ struct sarray *dtable;
+ struct objc_class *subclass_list;
+ struct objc_class *sibling_class;
+ }
+ struct objc_protocol_list *protocols;
+ }; */
+
+static void
+build_class_template ()
+{
+ tree decl_specs, field_decl, field_decl_chain;
+
+ objc_class_template
+ = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
+
+ /* struct objc_class *isa; */
+
+ decl_specs = build_tree_list (NULL_TREE, objc_class_template);
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl_chain = field_decl;
+
+ /* struct objc_class *super_class; */
+
+ decl_specs = build_tree_list (NULL_TREE, objc_class_template);
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* char *name; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* long version; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
+ field_decl = get_identifier ("version");
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* long info; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
+ field_decl = get_identifier ("info");
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* long instance_size; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
+ field_decl = get_identifier ("instance_size");
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* struct objc_ivar_list *ivars; */
+
+ decl_specs = build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_IVAR_LIST)));
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* struct objc_method_list *methods; */
+
+ decl_specs = build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_METHOD_LIST)));
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
+ field_decl
+ = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ if (flag_next_runtime)
+ {
+ /* struct objc_cache *cache; */
+
+ decl_specs = build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier ("objc_cache")));
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
+ field_decl = grokfield (input_filename, lineno, field_decl,
+ decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+ }
+ else
+ {
+ /* struct sarray *dtable; */
+
+ decl_specs = build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier ("sarray")));
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
+ field_decl = grokfield (input_filename, lineno, field_decl,
+ decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* struct objc_class *subclass_list; */
+
+ decl_specs = build_tree_list (NULL_TREE, objc_class_template);
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
+ field_decl = grokfield (input_filename, lineno, field_decl,
+ decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* struct objc_class *sibling_class; */
+
+ decl_specs = build_tree_list (NULL_TREE, objc_class_template);
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
+ field_decl = grokfield (input_filename, lineno, field_decl,
+ decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+ }
+
+ /* struct objc_protocol **protocol_list; */
+
+ decl_specs = build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_PROTOCOL)));
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, field_decl);
+ field_decl = grokfield (input_filename, lineno, field_decl,
+ decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+
+ finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
+}
+
+/* Generate appropriate forward declarations for an implementation. */
+
+static void
+synth_forward_declarations ()
+{
+ tree sc_spec, decl_specs, an_id;
+
+ /* extern struct objc_class _OBJC_CLASS_<my_name>; */
+
+ an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
+
+ sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
+ decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
+ UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
+ TREE_USED (UOBJC_CLASS_decl) = 1;
+ DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
+
+ /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
+
+ an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
+ implementation_context);
+
+ UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
+ TREE_USED (UOBJC_METACLASS_decl) = 1;
+ DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
+
+ /* Pre-build the following entities - for speed/convenience. */
+
+ an_id = get_identifier ("super_class");
+ ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
+ uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
+}
+
+static void
+error_with_ivar (message, decl, rawdecl)
+ char *message;
+ tree decl;
+ tree rawdecl;
+{
+ count_error (0);
+
+ report_error_function (DECL_SOURCE_FILE (decl));
+
+ fprintf (stderr, "%s:%d: ",
+ DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
+ bzero (errbuf, BUFSIZE);
+ fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
+}
+
+#define USERTYPE(t) \
+ (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
+ || TREE_CODE (t) == ENUMERAL_TYPE)
+
+static void
+check_ivars (inter, imp)
+ tree inter;
+ tree imp;
+{
+ tree intdecls = CLASS_IVARS (inter);
+ tree impdecls = CLASS_IVARS (imp);
+ tree rawintdecls = CLASS_RAW_IVARS (inter);
+ tree rawimpdecls = CLASS_RAW_IVARS (imp);
+
+ while (1)
+ {
+ tree t1, t2;
+
+ if (intdecls == 0 && impdecls == 0)
+ break;
+ if (intdecls == 0 || impdecls == 0)
+ {
+ error ("inconsistent instance variable specification");
+ break;
+ }
+
+ t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
+
+ if (!comptypes (t1, t2))
+ {
+ if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
+ {
+ error_with_ivar ("conflicting instance variable type",
+ impdecls, rawimpdecls);
+ error_with_ivar ("previous declaration of",
+ intdecls, rawintdecls);
+ }
+ else /* both the type and the name don't match */
+ {
+ error ("inconsistent instance variable specification");
+ break;
+ }
+ }
+
+ else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
+ {
+ error_with_ivar ("conflicting instance variable name",
+ impdecls, rawimpdecls);
+ error_with_ivar ("previous declaration of",
+ intdecls, rawintdecls);
+ }
+
+ intdecls = TREE_CHAIN (intdecls);
+ impdecls = TREE_CHAIN (impdecls);
+ rawintdecls = TREE_CHAIN (rawintdecls);
+ rawimpdecls = TREE_CHAIN (rawimpdecls);
+ }
+}
+
+/* Set super_type to the data type node for struct objc_super *,
+ first defining struct objc_super itself.
+ This needs to be done just once per compilation. */
+
+static tree
+build_super_template ()
+{
+ tree record, decl_specs, field_decl, field_decl_chain;
+
+ record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
+
+ /* struct objc_object *self; */
+
+ decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
+ field_decl = get_identifier ("self");
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
+ field_decl = grokfield (input_filename, lineno,
+ field_decl, decl_specs, NULL_TREE);
+ field_decl_chain = field_decl;
+
+ /* struct objc_class *class; */
+
+ decl_specs = get_identifier (UTAG_CLASS);
+ decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
+
+ field_decl = grokfield (input_filename, lineno,
+ field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ finish_struct (record, field_decl_chain, NULL_TREE);
+
+ /* `struct objc_super *' */
+ super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
+ record),
+ build1 (INDIRECT_REF,
+ NULL_TREE, NULL_TREE)));
+ return record;
+}
+
+/* struct objc_ivar {
+ char *ivar_name;
+ char *ivar_type;
+ int ivar_offset;
+ }; */
+
+static tree
+build_ivar_template ()
+{
+ tree objc_ivar_id, objc_ivar_record;
+ tree decl_specs, field_decl, field_decl_chain;
+
+ objc_ivar_id = get_identifier (UTAG_IVAR);
+ objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
+
+ /* char *ivar_name; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
+
+ field_decl = grokfield (input_filename, lineno, field_decl,
+ decl_specs, NULL_TREE);
+ field_decl_chain = field_decl;
+
+ /* char *ivar_type; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
+
+ field_decl = grokfield (input_filename, lineno, field_decl,
+ decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* int ivar_offset; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
+ field_decl = get_identifier ("ivar_offset");
+
+ field_decl = grokfield (input_filename, lineno, field_decl,
+ decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
+
+ return objc_ivar_record;
+}
+
+/* struct {
+ int ivar_count;
+ struct objc_ivar ivar_list[ivar_count];
+ }; */
+
+static tree
+build_ivar_list_template (list_type, size)
+ tree list_type;
+ int size;
+{
+ tree objc_ivar_list_record;
+ tree decl_specs, field_decl, field_decl_chain;
+
+ objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
+
+ /* int ivar_count; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
+ field_decl = get_identifier ("ivar_count");
+
+ field_decl = grokfield (input_filename, lineno, field_decl,
+ decl_specs, NULL_TREE);
+ field_decl_chain = field_decl;
+
+ /* struct objc_ivar ivar_list[]; */
+
+ decl_specs = build_tree_list (NULL_TREE, list_type);
+ field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
+ build_int_2 (size, 0));
+
+ field_decl = grokfield (input_filename, lineno,
+ field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
+
+ return objc_ivar_list_record;
+}
+
+/* struct {
+ int method_next;
+ int method_count;
+ struct objc_method method_list[method_count];
+ }; */
+
+static tree
+build_method_list_template (list_type, size)
+ tree list_type;
+ int size;
+{
+ tree objc_ivar_list_record;
+ tree decl_specs, field_decl, field_decl_chain;
+
+ objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
+
+ /* int method_next; */
+
+ decl_specs
+ = build_tree_list
+ (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
+ field_decl
+ = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
+ field_decl = grokfield (input_filename, lineno, field_decl,
+ decl_specs, NULL_TREE);
+ field_decl_chain = field_decl;
+
+ /* int method_count; */
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
+ field_decl = get_identifier ("method_count");
+
+ field_decl = grokfield (input_filename, lineno,
+ field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* struct objc_method method_list[]; */
+
+ decl_specs = build_tree_list (NULL_TREE, list_type);
+ field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
+ build_int_2 (size, 0));
+
+ field_decl = grokfield (input_filename, lineno,
+ field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
+
+ return objc_ivar_list_record;
+}
+
+static tree
+build_ivar_list_initializer (type, field_decl)
+ tree type;
+ tree field_decl;
+{
+ tree initlist = NULL_TREE;
+
+ do
+ {
+ tree ivar = NULL_TREE;
+
+ /* Set name. */
+ if (DECL_NAME (field_decl))
+ ivar = tree_cons (NULL_TREE,
+ add_objc_string (DECL_NAME (field_decl),
+ meth_var_names),
+ ivar);
+ else
+ /* Unnamed bit-field ivar (yuck). */
+ ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
+
+ /* Set type. */
+ encode_field_decl (field_decl,
+ obstack_object_size (&util_obstack),
+ OBJC_ENCODE_DONT_INLINE_DEFS);
+
+ /* Null terminate string. */
+ obstack_1grow (&util_obstack, 0);
+ ivar
+ = tree_cons
+ (NULL_TREE,
+ add_objc_string (get_identifier (obstack_finish (&util_obstack)),
+ meth_var_types),
+ ivar);
+ obstack_free (&util_obstack, util_firstobj);
+
+ /* set offset */
+ ivar
+ = tree_cons
+ (NULL_TREE,
+ build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
+ / BITS_PER_UNIT),
+ 0),
+ ivar);
+
+ initlist = tree_cons (NULL_TREE,
+ build_constructor (type, nreverse (ivar)),
+ initlist);
+
+ field_decl = TREE_CHAIN (field_decl);
+ }
+ while (field_decl);
+
+ return build_constructor (build_array_type (type, 0), nreverse (initlist));
+}
+
+static tree
+generate_ivars_list (type, name, size, list)
+ tree type;
+ char *name;
+ int size;
+ tree list;
+{
+ tree sc_spec, decl_specs, decl, initlist;
+
+ sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+ decl_specs = tree_cons (NULL_TREE, type, sc_spec);
+
+ decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
+ decl_specs, 1, NULL_TREE, NULL_TREE);
+
+ initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
+ initlist = tree_cons (NULL_TREE, list, initlist);
+
+ finish_decl (decl,
+ build_constructor (TREE_TYPE (decl), nreverse (initlist)),
+ NULL_TREE);
+
+ return decl;
+}
+
+static void
+generate_ivar_lists ()
+{
+ tree initlist, ivar_list_template, chain;
+ tree cast, variable_length_type;
+ int size;
+
+ generating_instance_variables = 1;
+
+ if (!objc_ivar_template)
+ objc_ivar_template = build_ivar_template ();
+
+ cast
+ = build_tree_list
+ (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_IVAR_LIST))),
+ NULL_TREE);
+ variable_length_type = groktypename (cast);
+
+ /* Only generate class variables for the root of the inheritance
+ hierarchy since these will be the same for every class. */
+
+ if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
+ && (chain = TYPE_FIELDS (objc_class_template)))
+ {
+ size = list_length (chain);
+
+ ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
+ initlist = build_ivar_list_initializer (objc_ivar_template, chain);
+
+ UOBJC_CLASS_VARIABLES_decl
+ = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
+ size, initlist);
+ TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
+ }
+ else
+ UOBJC_CLASS_VARIABLES_decl = 0;
+
+ chain = CLASS_IVARS (implementation_template);
+ if (chain)
+ {
+ size = list_length (chain);
+ ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
+ initlist = build_ivar_list_initializer (objc_ivar_template, chain);
+
+ UOBJC_INSTANCE_VARIABLES_decl
+ = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
+ size, initlist);
+ TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
+ }
+ else
+ UOBJC_INSTANCE_VARIABLES_decl = 0;
+
+ generating_instance_variables = 0;
+}
+
+static tree
+build_dispatch_table_initializer (type, entries)
+ tree type;
+ tree entries;
+{
+ tree initlist = NULL_TREE;
+
+ do
+ {
+ tree elemlist = NULL_TREE;
+
+ elemlist = tree_cons (NULL_TREE,
+ build_selector (METHOD_SEL_NAME (entries)),
+ NULL_TREE);
+
+ elemlist = tree_cons (NULL_TREE,
+ add_objc_string (METHOD_ENCODING (entries),
+ meth_var_types),
+ elemlist);
+
+ elemlist = tree_cons (NULL_TREE,
+ build_unary_op (ADDR_EXPR,
+ METHOD_DEFINITION (entries), 1),
+ elemlist);
+
+ initlist = tree_cons (NULL_TREE,
+ build_constructor (type, nreverse (elemlist)),
+ initlist);
+
+ entries = TREE_CHAIN (entries);
+ }
+ while (entries);
+
+ return build_constructor (build_array_type (type, 0), nreverse (initlist));
+}
+
+/* To accomplish method prototyping without generating all kinds of
+ inane warnings, the definition of the dispatch table entries were
+ changed from:
+
+ struct objc_method { SEL _cmd; ...; id (*_imp)(); };
+ to:
+ struct objc_method { SEL _cmd; ...; void *_imp; }; */
+
+static tree
+build_method_template ()
+{
+ tree _SLT_record;
+ tree decl_specs, field_decl, field_decl_chain;
+
+ _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
+
+#ifdef OBJC_INT_SELECTORS
+ /* unsigned int _cmd; */
+ decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED],
+ NULL_TREE);
+ decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
+ field_decl = get_identifier ("_cmd");
+#else /* not OBJC_INT_SELECTORS */
+ /* struct objc_selector *_cmd; */
+ decl_specs = tree_cons (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (TAG_SELECTOR)),
+ NULL_TREE);
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
+#endif /* not OBJC_INT_SELECTORS */
+
+ field_decl = grokfield (input_filename, lineno, field_decl,
+ decl_specs, NULL_TREE);
+ field_decl_chain = field_decl;
+
+ decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
+ field_decl = build1 (INDIRECT_REF, NULL_TREE,
+ get_identifier ("method_types"));
+ field_decl = grokfield (input_filename, lineno, field_decl,
+ decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ /* void *_imp; */
+
+ decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
+ field_decl = grokfield (input_filename, lineno, field_decl,
+ decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+
+ finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
+
+ return _SLT_record;
+}
+
+
+static tree
+generate_dispatch_table (type, name, size, list)
+ tree type;
+ char *name;
+ int size;
+ tree list;
+{
+ tree sc_spec, decl_specs, decl, initlist;
+
+ sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+ decl_specs = tree_cons (NULL_TREE, type, sc_spec);
+
+ decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
+ decl_specs, 1, NULL_TREE, NULL_TREE);
+
+ initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
+ initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
+ initlist = tree_cons (NULL_TREE, list, initlist);
+
+ finish_decl (decl,
+ build_constructor (TREE_TYPE (decl), nreverse (initlist)),
+ NULL_TREE);
+
+ return decl;
+}
+
+static void
+generate_dispatch_tables ()
+{
+ tree initlist, chain, method_list_template;
+ tree cast, variable_length_type;
+ int size;
+
+ if (!objc_method_template)
+ objc_method_template = build_method_template ();
+
+ cast
+ = build_tree_list
+ (build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_METHOD_LIST))),
+ NULL_TREE);
+
+ variable_length_type = groktypename (cast);
+
+ chain = CLASS_CLS_METHODS (implementation_context);
+ if (chain)
+ {
+ size = list_length (chain);
+
+ method_list_template
+ = build_method_list_template (objc_method_template, size);
+ initlist
+ = build_dispatch_table_initializer (objc_method_template, chain);
+
+ UOBJC_CLASS_METHODS_decl
+ = generate_dispatch_table (method_list_template,
+ ((TREE_CODE (implementation_context)
+ == CLASS_IMPLEMENTATION_TYPE)
+ ? "_OBJC_CLASS_METHODS"
+ : "_OBJC_CATEGORY_CLASS_METHODS"),
+ size, initlist);
+ TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
+ }
+ else
+ UOBJC_CLASS_METHODS_decl = 0;
+
+ chain = CLASS_NST_METHODS (implementation_context);
+ if (chain)
+ {
+ size = list_length (chain);
+
+ method_list_template
+ = build_method_list_template (objc_method_template, size);
+ initlist
+ = build_dispatch_table_initializer (objc_method_template, chain);
+
+ if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
+ UOBJC_INSTANCE_METHODS_decl
+ = generate_dispatch_table (method_list_template,
+ "_OBJC_INSTANCE_METHODS",
+ size, initlist);
+ else
+ /* We have a category. */
+ UOBJC_INSTANCE_METHODS_decl
+ = generate_dispatch_table (method_list_template,
+ "_OBJC_CATEGORY_INSTANCE_METHODS",
+ size, initlist);
+ TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
+ }
+ else
+ UOBJC_INSTANCE_METHODS_decl = 0;
+}
+
+static tree
+generate_protocol_list (i_or_p)
+ tree i_or_p;
+{
+ static tree cast_type = 0;
+ tree initlist, decl_specs, sc_spec;
+ tree refs_decl, expr_decl, lproto, e, plist;
+ int size = 0;
+
+ if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
+ || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
+ plist = CLASS_PROTOCOL_LIST (i_or_p);
+ else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
+ plist = PROTOCOL_LIST (i_or_p);
+ else
+ abort ();
+
+ if (!cast_type)
+ cast_type
+ = groktypename
+ (build_tree_list
+ (build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_PROTOCOL))),
+ build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
+
+ /* Compute size. */
+ for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
+ if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
+ && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
+ size++;
+
+ /* Build initializer. */
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
+
+ e = build_int_2 (size, 0);
+ TREE_TYPE (e) = cast_type;
+ initlist = tree_cons (NULL_TREE, e, initlist);
+
+ for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
+ {
+ tree pval = TREE_VALUE (lproto);
+
+ if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
+ && PROTOCOL_FORWARD_DECL (pval))
+ {
+ e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
+ initlist = tree_cons (NULL_TREE, e, initlist);
+ }
+ }
+
+ /* static struct objc_protocol *refs[n]; */
+
+ sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+ decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_PROTOCOL)),
+ sc_spec);
+
+ if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
+ expr_decl = build_nt (ARRAY_REF,
+ synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
+ i_or_p),
+ build_int_2 (size + 2, 0));
+ else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
+ expr_decl = build_nt (ARRAY_REF,
+ synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
+ i_or_p),
+ build_int_2 (size + 2, 0));
+ else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
+ expr_decl
+ = build_nt (ARRAY_REF,
+ synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
+ i_or_p),
+ build_int_2 (size + 2, 0));
+
+ expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
+
+ refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
+
+ finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
+ nreverse (initlist)),
+ NULL_TREE);
+
+ return refs_decl;
+}
+
+static tree
+build_category_initializer (type, cat_name, class_name,
+ instance_methods, class_methods, protocol_list)
+ tree type;
+ tree cat_name;
+ tree class_name;
+ tree instance_methods;
+ tree class_methods;
+ tree protocol_list;
+{
+ tree initlist = NULL_TREE, expr;
+
+ initlist = tree_cons (NULL_TREE, cat_name, initlist);
+ initlist = tree_cons (NULL_TREE, class_name, initlist);
+
+ if (!instance_methods)
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+ else
+ {
+ expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
+ if (!class_methods)
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+ else
+ {
+ expr = build_unary_op (ADDR_EXPR, class_methods, 0);
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
+
+ /* protocol_list = */
+ if (!protocol_list)
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+ else
+ {
+ static tree cast_type2;
+
+ if (!cast_type2)
+ cast_type2
+ = groktypename
+ (build_tree_list
+ (build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_PROTOCOL))),
+ build1 (INDIRECT_REF, NULL_TREE,
+ build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
+
+ expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
+ TREE_TYPE (expr) = cast_type2;
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
+
+ return build_constructor (type, nreverse (initlist));
+}
+
+/* struct objc_class {
+ struct objc_class *isa;
+ struct objc_class *super_class;
+ char *name;
+ long version;
+ long info;
+ long instance_size;
+ struct objc_ivar_list *ivars;
+ struct objc_method_list *methods;
+ if (flag_next_runtime)
+ struct objc_cache *cache;
+ else {
+ struct sarray *dtable;
+ struct objc_class *subclass_list;
+ struct objc_class *sibling_class;
+ }
+ struct objc_protocol_list *protocols;
+ }; */
+
+static tree
+build_shared_structure_initializer (type, isa, super, name, size, status,
+ dispatch_table, ivar_list, protocol_list)
+ tree type;
+ tree isa;
+ tree super;
+ tree name;
+ tree size;
+ int status;
+ tree dispatch_table;
+ tree ivar_list;
+ tree protocol_list;
+{
+ tree initlist = NULL_TREE, expr;
+
+ /* isa = */
+ initlist = tree_cons (NULL_TREE, isa, initlist);
+
+ /* super_class = */
+ initlist = tree_cons (NULL_TREE, super, initlist);
+
+ /* name = */
+ initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
+
+ /* version = */
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+
+ /* info = */
+ initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
+
+ /* instance_size = */
+ initlist = tree_cons (NULL_TREE, size, initlist);
+
+ /* objc_ivar_list = */
+ if (!ivar_list)
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+ else
+ {
+ expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
+
+ /* objc_method_list = */
+ if (!dispatch_table)
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+ else
+ {
+ expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
+
+ if (flag_next_runtime)
+ /* method_cache = */
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+ else
+ {
+ /* dtable = */
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+
+ /* subclass_list = */
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+
+ /* sibling_class = */
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+ }
+
+ /* protocol_list = */
+ if (! protocol_list)
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+ else
+ {
+ static tree cast_type2;
+
+ if (!cast_type2)
+ cast_type2
+ = groktypename
+ (build_tree_list
+ (build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_PROTOCOL))),
+ build1 (INDIRECT_REF, NULL_TREE,
+ build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
+
+ expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
+ TREE_TYPE (expr) = cast_type2;
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
+
+ return build_constructor (type, nreverse (initlist));
+}
+
+/* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
+
+static void
+generate_category (cat)
+ tree cat;
+{
+ tree sc_spec, decl_specs, decl;
+ tree initlist, cat_name_expr, class_name_expr;
+ tree protocol_decl, category;
+
+ add_class_reference (CLASS_NAME (cat));
+ cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
+
+ class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
+
+ category = CLASS_CATEGORY_LIST (implementation_template);
+
+ /* find the category interface from the class it is associated with */
+ while (category)
+ {
+ if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
+ break;
+ category = CLASS_CATEGORY_LIST (category);
+ }
+
+ if (category && CLASS_PROTOCOL_LIST (category))
+ {
+ generate_protocol_references (CLASS_PROTOCOL_LIST (category));
+ protocol_decl = generate_protocol_list (category);
+ }
+ else
+ protocol_decl = 0;
+
+ sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+ decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
+
+ decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
+ implementation_context),
+ decl_specs, 1, NULL_TREE, NULL_TREE);
+
+ initlist = build_category_initializer (TREE_TYPE (decl),
+ cat_name_expr, class_name_expr,
+ UOBJC_INSTANCE_METHODS_decl,
+ UOBJC_CLASS_METHODS_decl,
+ protocol_decl);
+
+ TREE_USED (decl) = 1;
+ finish_decl (decl, initlist, NULL_TREE);
+}
+
+/* static struct objc_class _OBJC_METACLASS_Foo={ ... };
+ static struct objc_class _OBJC_CLASS_Foo={ ... }; */
+
+static void
+generate_shared_structures ()
+{
+ tree sc_spec, decl_specs, decl;
+ tree name_expr, super_expr, root_expr;
+ tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
+ tree cast_type, initlist, protocol_decl;
+
+ my_super_id = CLASS_SUPER_NAME (implementation_template);
+ if (my_super_id)
+ {
+ add_class_reference (my_super_id);
+
+ /* Compute "my_root_id" - this is required for code generation.
+ the "isa" for all meta class structures points to the root of
+ the inheritance hierarchy (e.g. "__Object")... */
+ my_root_id = my_super_id;
+ do
+ {
+ tree my_root_int = lookup_interface (my_root_id);
+
+ if (my_root_int && CLASS_SUPER_NAME (my_root_int))
+ my_root_id = CLASS_SUPER_NAME (my_root_int);
+ else
+ break;
+ }
+ while (1);
+ }
+ else
+ /* No super class. */
+ my_root_id = CLASS_NAME (implementation_template);
+
+ cast_type
+ = groktypename (build_tree_list (build_tree_list (NULL_TREE,
+ objc_class_template),
+ build1 (INDIRECT_REF,
+ NULL_TREE, NULL_TREE)));
+
+ name_expr = add_objc_string (CLASS_NAME (implementation_template),
+ class_names);
+
+ /* Install class `isa' and `super' pointers at runtime. */
+ if (my_super_id)
+ {
+ super_expr = add_objc_string (my_super_id, class_names);
+ super_expr = build_c_cast (cast_type, super_expr); /* cast! */
+ }
+ else
+ super_expr = build_int_2 (0, 0);
+
+ root_expr = add_objc_string (my_root_id, class_names);
+ root_expr = build_c_cast (cast_type, root_expr); /* cast! */
+
+ if (CLASS_PROTOCOL_LIST (implementation_template))
+ {
+ generate_protocol_references
+ (CLASS_PROTOCOL_LIST (implementation_template));
+ protocol_decl = generate_protocol_list (implementation_template);
+ }
+ else
+ protocol_decl = 0;
+
+ /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
+
+ sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
+ decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
+
+ decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
+ NULL_TREE, NULL_TREE);
+
+ initlist
+ = build_shared_structure_initializer
+ (TREE_TYPE (decl),
+ root_expr, super_expr, name_expr,
+ build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template))
+ / BITS_PER_UNIT),
+ 0),
+ 2 /*CLS_META*/,
+ UOBJC_CLASS_METHODS_decl,
+ UOBJC_CLASS_VARIABLES_decl,
+ protocol_decl);
+
+ finish_decl (decl, initlist, NULL_TREE);
+
+ /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
+
+ decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
+ NULL_TREE, NULL_TREE);
+
+ initlist
+ = build_shared_structure_initializer
+ (TREE_TYPE (decl),
+ build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
+ super_expr, name_expr,
+ build_int_2
+ ((TREE_INT_CST_LOW
+ (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template)))
+ / BITS_PER_UNIT),
+ 0),
+ 1 /*CLS_FACTORY*/,
+ UOBJC_INSTANCE_METHODS_decl,
+ UOBJC_INSTANCE_VARIABLES_decl,
+ protocol_decl);
+
+ finish_decl (decl, initlist, NULL_TREE);
+}
+
+static tree
+synth_id_with_class_suffix (preamble, ctxt)
+ char *preamble;
+ tree ctxt;
+{
+ char *string;
+ if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
+ || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
+ {
+ char *class_name
+ = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
+ string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
+ sprintf (string, "%s_%s", preamble,
+ IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
+ }
+ else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
+ || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
+ {
+ /* We have a category. */
+ char *class_name
+ = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
+ char *class_super_name
+ = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
+ string = (char *) alloca (strlen (preamble)
+ + strlen (class_name)
+ + strlen (class_super_name)
+ + 3);
+ sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
+ }
+ else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
+ {
+ char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
+ string
+ = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
+ sprintf (string, "%s_%s", preamble, protocol_name);
+ }
+ return get_identifier (string);
+}
+
+static int
+is_objc_type_qualifier (node)
+ tree node;
+{
+ return (TREE_CODE (node) == IDENTIFIER_NODE
+ && (node == ridpointers [(int) RID_CONST]
+ || node == ridpointers [(int) RID_VOLATILE]
+ || node == ridpointers [(int) RID_IN]
+ || node == ridpointers [(int) RID_OUT]
+ || node == ridpointers [(int) RID_INOUT]
+ || node == ridpointers [(int) RID_BYCOPY]
+ || node == ridpointers [(int) RID_ONEWAY]));
+}
+
+/* If type is empty or only type qualifiers are present, add default
+ type of id (otherwise grokdeclarator will default to int). */
+
+static tree
+adjust_type_for_id_default (type)
+ tree type;
+{
+ tree declspecs, chain;
+
+ if (!type)
+ return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
+ build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
+
+ declspecs = TREE_PURPOSE (type);
+
+ /* Determine if a typespec is present. */
+ for (chain = declspecs;
+ chain;
+ chain = TREE_CHAIN (chain))
+ {
+ if (!is_objc_type_qualifier (TREE_VALUE (chain)))
+ return type;
+ }
+
+ return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
+ declspecs),
+ build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
+}
+
+/* Usage:
+ keyworddecl:
+ selector ':' '(' typename ')' identifier
+
+ Purpose:
+ Transform an Objective-C keyword argument into
+ the C equivalent parameter declarator.
+
+ In: key_name, an "identifier_node" (optional).
+ arg_type, a "tree_list" (optional).
+ arg_name, an "identifier_node".
+
+ Note: It would be really nice to strongly type the preceding
+ arguments in the function prototype; however, then I
+ could not use the "accessor" macros defined in "tree.h".
+
+ Out: an instance of "keyword_decl". */
+
+tree
+build_keyword_decl (key_name, arg_type, arg_name)
+ tree key_name;
+ tree arg_type;
+ tree arg_name;
+{
+ tree keyword_decl;
+
+ /* If no type is specified, default to "id". */
+ arg_type = adjust_type_for_id_default (arg_type);
+
+ keyword_decl = make_node (KEYWORD_DECL);
+
+ TREE_TYPE (keyword_decl) = arg_type;
+ KEYWORD_ARG_NAME (keyword_decl) = arg_name;
+ KEYWORD_KEY_NAME (keyword_decl) = key_name;
+
+ return keyword_decl;
+}
+
+/* Given a chain of keyword_decl's, synthesize the full keyword selector. */
+
+static tree
+build_keyword_selector (selector)
+ tree selector;
+{
+ int len = 0;
+ tree key_chain, key_name;
+ char *buf;
+
+ for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
+ {
+ if (TREE_CODE (selector) == KEYWORD_DECL)
+ key_name = KEYWORD_KEY_NAME (key_chain);
+ else if (TREE_CODE (selector) == TREE_LIST)
+ key_name = TREE_PURPOSE (key_chain);
+
+ if (key_name)
+ len += IDENTIFIER_LENGTH (key_name) + 1;
+ else
+ /* Just a ':' arg. */
+ len++;
+ }
+
+ buf = (char *)alloca (len + 1);
+ bzero (buf, len + 1);
+
+ for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
+ {
+ if (TREE_CODE (selector) == KEYWORD_DECL)
+ key_name = KEYWORD_KEY_NAME (key_chain);
+ else if (TREE_CODE (selector) == TREE_LIST)
+ key_name = TREE_PURPOSE (key_chain);
+
+ if (key_name)
+ strcat (buf, IDENTIFIER_POINTER (key_name));
+ strcat (buf, ":");
+ }
+
+ return get_identifier (buf);
+}
+
+/* Used for declarations and definitions. */
+
+tree
+build_method_decl (code, ret_type, selector, add_args)
+ enum tree_code code;
+ tree ret_type;
+ tree selector;
+ tree add_args;
+{
+ tree method_decl;
+
+ /* If no type is specified, default to "id". */
+ ret_type = adjust_type_for_id_default (ret_type);
+
+ method_decl = make_node (code);
+ TREE_TYPE (method_decl) = ret_type;
+
+ /* If we have a keyword selector, create an identifier_node that
+ represents the full selector name (`:' included)... */
+ if (TREE_CODE (selector) == KEYWORD_DECL)
+ {
+ METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
+ METHOD_SEL_ARGS (method_decl) = selector;
+ METHOD_ADD_ARGS (method_decl) = add_args;
+ }
+ else
+ {
+ METHOD_SEL_NAME (method_decl) = selector;
+ METHOD_SEL_ARGS (method_decl) = NULL_TREE;
+ METHOD_ADD_ARGS (method_decl) = NULL_TREE;
+ }
+
+ return method_decl;
+}
+
+#define METHOD_DEF 0
+#define METHOD_REF 1
+
+/* Used by `build_message_expr' and `comp_method_types'. Return an
+ argument list for method METH. CONTEXT is either METHOD_DEF or
+ METHOD_REF, saying whether we are trying to define a method or call
+ one. SUPERFLAG says this is for a send to super; this makes a
+ difference for the NeXT calling sequence in which the lookup and
+ the method call are done together. */
+
+static tree
+get_arg_type_list (meth, context, superflag)
+ tree meth;
+ int context;
+ int superflag;
+{
+ tree arglist, akey;
+
+ /* Receiver type. */
+ if (flag_next_runtime && superflag)
+ arglist = build_tree_list (NULL_TREE, super_type);
+ else if (context == METHOD_DEF)
+ arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
+ else
+ arglist = build_tree_list (NULL_TREE, id_type);
+
+ /* Selector type - will eventually change to `int'. */
+ chainon (arglist, build_tree_list (NULL_TREE, selector_type));
+
+ /* Build a list of argument types. */
+ for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
+ {
+ tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
+ chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
+ }
+
+ if (METHOD_ADD_ARGS (meth) == (tree)1)
+ /* We have a `, ...' immediately following the selector,
+ finalize the arglist...simulate get_parm_info (0). */
+ ;
+ else if (METHOD_ADD_ARGS (meth))
+ {
+ /* we have a variable length selector */
+ tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
+ chainon (arglist, add_arg_list);
+ }
+ else
+ /* finalize the arglist...simulate get_parm_info (1) */
+ chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
+
+ return arglist;
+}
+
+static tree
+check_duplicates (hsh)
+ hash hsh;
+{
+ tree meth = NULL_TREE;
+
+ if (hsh)
+ {
+ meth = hsh->key;
+
+ if (hsh->list)
+ {
+ /* We have two methods with the same name and different types. */
+ attr loop;
+ char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
+
+ warning ("multiple declarations for method `%s'",
+ IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
+
+ warn_with_method ("using", type, meth);
+ for (loop = hsh->list; loop; loop = loop->next)
+ warn_with_method ("also found", type, loop->value);
+ }
+ }
+ return meth;
+}
+
+/* If RECEIVER is a class reference, return the identifier node for the
+ referenced class. RECEIVER is created by get_class_reference, so we
+ check the exact form created depending on which runtimes are used. */
+
+static tree
+receiver_is_class_object (receiver)
+ tree receiver;
+{
+ tree chain, exp, arg;
+ if (flag_next_runtime)
+ {
+ /* The receiver is a variable created by build_class_reference_decl. */
+ if (TREE_CODE (receiver) == VAR_DECL
+ && TREE_TYPE (receiver) == objc_class_type)
+ /* Look up the identifier. */
+ for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
+ if (TREE_PURPOSE (chain) == receiver)
+ return TREE_VALUE (chain);
+ }
+ else
+ {
+ /* The receiver is a function call that returns an id. Check if
+ it is a call to objc_getClass, if so, pick up the class name. */
+ if ((exp = TREE_OPERAND (receiver, 0))
+ && TREE_CODE (exp) == ADDR_EXPR
+ && (exp = TREE_OPERAND (exp, 0))
+ && TREE_CODE (exp) == FUNCTION_DECL
+ && exp == objc_get_class_decl
+ /* we have a call to objc_getClass! */
+ && (arg = TREE_OPERAND (receiver, 1))
+ && TREE_CODE (arg) == TREE_LIST
+ && (arg = TREE_VALUE (arg)))
+ {
+ STRIP_NOPS (arg);
+ if (TREE_CODE (arg) == ADDR_EXPR
+ && (arg = TREE_OPERAND (arg, 0))
+ && TREE_CODE (arg) == STRING_CST)
+ /* Finally, we have the class name. */
+ return get_identifier (TREE_STRING_POINTER (arg));
+ }
+ }
+ return 0;
+}
+
+/* If we are currently building a message expr, this holds
+ the identifier of the selector of the message. This is
+ used when printing warnings about argument mismatches. */
+
+static tree building_objc_message_expr = 0;
+
+tree
+maybe_building_objc_message_expr ()
+{
+ return building_objc_message_expr;
+}
+
+/* Construct an expression for sending a message.
+ MESS has the object to send to in TREE_PURPOSE
+ and the argument list (including selector) in TREE_VALUE.
+
+ (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
+ (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
+
+tree
+build_message_expr (mess)
+ tree mess;
+{
+ tree receiver = TREE_PURPOSE (mess);
+ tree selector, self_object;
+ tree rtype, sel_name;
+ tree args = TREE_VALUE (mess);
+ tree method_params = NULL_TREE;
+ tree method_prototype = NULL_TREE;
+ tree retval;
+ int statically_typed = 0, statically_allocated = 0;
+ tree class_ident = 0;
+
+ /* 1 if this is sending to the superclass. */
+ int super;
+
+ if (!doing_objc_thang)
+ objc_fatal ();
+
+ if (TREE_CODE (receiver) == ERROR_MARK)
+ return error_mark_node;
+
+ /* Determine receiver type. */
+ rtype = TREE_TYPE (receiver);
+ super = IS_SUPER (rtype);
+
+ if (! super)
+ {
+ if (TREE_STATIC_TEMPLATE (rtype))
+ statically_allocated = 1;
+ else if (TREE_CODE (rtype) == POINTER_TYPE
+ && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
+ statically_typed = 1;
+ else if ((flag_next_runtime
+ || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
+ && (class_ident = receiver_is_class_object (receiver)))
+ ;
+ else if (! IS_ID (rtype)
+ /* Allow any type that matches objc_class_type. */
+ && ! comptypes (rtype, objc_class_type))
+ {
+ bzero (errbuf, BUFSIZE);
+ warning ("invalid receiver type `%s'",
+ gen_declaration (rtype, errbuf));
+ }
+
+ if (statically_allocated)
+ receiver = build_unary_op (ADDR_EXPR, receiver, 0);
+
+ /* Don't evaluate the receiver twice. */
+ receiver = save_expr (receiver);
+ self_object = receiver;
+ }
+ else
+ /* If sending to `super', use current self as the object. */
+ self_object = self_decl;
+
+ /* Obtain the full selector name. */
+
+ if (TREE_CODE (args) == IDENTIFIER_NODE)
+ /* A unary selector. */
+ sel_name = args;
+ else if (TREE_CODE (args) == TREE_LIST)
+ sel_name = build_keyword_selector (args);
+
+ /* Build the parameter list to give to the method. */
+
+ method_params = NULL_TREE;
+ if (TREE_CODE (args) == TREE_LIST)
+ {
+ tree chain = args, prev = NULL_TREE;
+
+ /* We have a keyword selector--check for comma expressions. */
+ while (chain)
+ {
+ tree element = TREE_VALUE (chain);
+
+ /* We have a comma expression, must collapse... */
+ if (TREE_CODE (element) == TREE_LIST)
+ {
+ if (prev)
+ TREE_CHAIN (prev) = element;
+ else
+ args = element;
+ }
+ prev = chain;
+ chain = TREE_CHAIN (chain);
+ }
+ method_params = args;
+ }
+
+ /* Determine operation return type. */
+
+ if (IS_SUPER (rtype))
+ {
+ tree iface;
+
+ if (CLASS_SUPER_NAME (implementation_template))
+ {
+ iface
+ = lookup_interface (CLASS_SUPER_NAME (implementation_template));
+
+ if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
+ method_prototype = lookup_instance_method_static (iface, sel_name);
+ else
+ method_prototype = lookup_class_method_static (iface, sel_name);
+
+ if (iface && !method_prototype)
+ warning ("`%s' does not respond to `%s'",
+ IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
+ IDENTIFIER_POINTER (sel_name));
+ }
+ else
+ {
+ error ("no super class declared in interface for `%s'",
+ IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
+ return error_mark_node;
+ }
+
+ }
+ else if (statically_allocated)
+ {
+ tree ctype = TREE_TYPE (rtype);
+ tree iface = lookup_interface (TYPE_NAME (rtype));
+
+ if (iface)
+ method_prototype = lookup_instance_method_static (iface, sel_name);
+
+ if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
+ method_prototype
+ = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
+ sel_name, 0);
+
+ if (!method_prototype)
+ warning ("`%s' does not respond to `%s'",
+ IDENTIFIER_POINTER (TYPE_NAME (rtype)),
+ IDENTIFIER_POINTER (sel_name));
+ }
+ else if (statically_typed)
+ {
+ tree ctype = TREE_TYPE (rtype);
+
+ /* `self' is now statically_typed. All methods should be visible
+ within the context of the implementation. */
+ if (implementation_context
+ && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
+ {
+ method_prototype
+ = lookup_instance_method_static (implementation_template,
+ sel_name);
+
+ if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
+ method_prototype
+ = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
+ sel_name, 0);
+
+ if (! method_prototype
+ && implementation_template != implementation_context)
+ /* The method is not published in the interface. Check
+ locally. */
+ method_prototype
+ = lookup_method (CLASS_NST_METHODS (implementation_context),
+ sel_name);
+ }
+ else
+ {
+ tree iface;
+
+ if ((iface = lookup_interface (TYPE_NAME (ctype))))
+ method_prototype = lookup_instance_method_static (iface, sel_name);
+
+ if (! method_prototype)
+ {
+ tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
+ if (protocol_list)
+ method_prototype
+ = lookup_method_in_protocol_list (protocol_list,
+ sel_name, 0);
+ }
+ }
+
+ if (!method_prototype)
+ warning ("`%s' does not respond to `%s'",
+ IDENTIFIER_POINTER (TYPE_NAME (ctype)),
+ IDENTIFIER_POINTER (sel_name));
+ }
+ else if (class_ident)
+ {
+ if (implementation_context
+ && CLASS_NAME (implementation_context) == class_ident)
+ {
+ method_prototype
+ = lookup_class_method_static (implementation_template, sel_name);
+
+ if (!method_prototype
+ && implementation_template != implementation_context)
+ /* The method is not published in the interface. Check
+ locally. */
+ method_prototype
+ = lookup_method (CLASS_CLS_METHODS (implementation_context),
+ sel_name);
+ }
+ else
+ {
+ tree iface;
+
+ if ((iface = lookup_interface (class_ident)))
+ method_prototype = lookup_class_method_static (iface, sel_name);
+ }
+
+ if (!method_prototype)
+ {
+ warning ("cannot find class (factory) method.");
+ warning ("return type for `%s' defaults to id",
+ IDENTIFIER_POINTER (sel_name));
+ }
+ }
+ else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
+ {
+ /* An anonymous object that has been qualified with a protocol. */
+
+ tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
+
+ method_prototype = lookup_method_in_protocol_list (protocol_list,
+ sel_name, 0);
+
+ if (!method_prototype)
+ {
+ hash hsh;
+
+ warning ("method `%s' not implemented by protocol.",
+ IDENTIFIER_POINTER (sel_name));
+
+ /* Try and find the method signature in the global pools. */
+
+ if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
+ hsh = hash_lookup (cls_method_hash_list, sel_name);
+
+ if (!(method_prototype = check_duplicates (hsh)))
+ warning ("return type defaults to id");
+ }
+ }
+ else
+ {
+ hash hsh;
+
+ /* We think we have an instance...loophole: extern id Object; */
+ hsh = hash_lookup (nst_method_hash_list, sel_name);
+ if (!hsh)
+ /* For various loopholes, like sending messages to self in a
+ factory context. */
+ hsh = hash_lookup (cls_method_hash_list, sel_name);
+
+ method_prototype = check_duplicates (hsh);
+ if (!method_prototype)
+ {
+ warning ("cannot find method.");
+ warning ("return type for `%s' defaults to id",
+ IDENTIFIER_POINTER (sel_name));
+ }
+ }
+
+ /* Save the selector name for printing error messages. */
+ building_objc_message_expr = sel_name;
+
+ /* Build the parameters list for looking up the method.
+ These are the object itself and the selector. */
+
+ if (flag_typed_selectors)
+ selector = build_typed_selector_reference (sel_name, method_prototype);
+ else
+ selector = build_selector_reference (sel_name);
+
+ retval = build_objc_method_call (super, method_prototype,
+ receiver, self_object,
+ selector, method_params);
+
+ building_objc_message_expr = 0;
+
+ return retval;
+}
+
+/* Build a tree expression to send OBJECT the operation SELECTOR,
+ looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
+ assuming the method has prototype METHOD_PROTOTYPE.
+ (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
+ Use METHOD_PARAMS as list of args to pass to the method.
+ If SUPER_FLAG is nonzero, we look up the superclass's method. */
+
+static tree
+build_objc_method_call (super_flag, method_prototype, lookup_object, object,
+ selector, method_params)
+ int super_flag;
+ tree method_prototype, lookup_object, object, selector, method_params;
+{
+ tree sender = (super_flag ? umsg_super_decl : umsg_decl);
+ tree rcv_p = (super_flag
+ ? build_pointer_type (xref_tag (RECORD_TYPE,
+ get_identifier (TAG_SUPER)))
+ : id_type);
+
+ if (flag_next_runtime)
+ {
+ if (! method_prototype)
+ {
+ method_params = tree_cons (NULL_TREE, lookup_object,
+ tree_cons (NULL_TREE, selector,
+ method_params));
+ assemble_external (sender);
+ return build_function_call (sender, method_params);
+ }
+ else
+ {
+ /* This is a real kludge, but it is used only for the Next.
+ Clobber the data type of SENDER temporarily to accept
+ all the arguments for this operation, and to return
+ whatever this operation returns. */
+ tree arglist = NULL_TREE;
+ tree retval;
+
+ /* Save the proper contents of SENDER's data type. */
+ tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
+ tree savret = TREE_TYPE (TREE_TYPE (sender));
+
+ /* Install this method's argument types. */
+ arglist = get_arg_type_list (method_prototype, METHOD_REF,
+ super_flag);
+ TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
+
+ /* Install this method's return type. */
+ TREE_TYPE (TREE_TYPE (sender))
+ = groktypename (TREE_TYPE (method_prototype));
+
+ /* Call SENDER with all the parameters. This will do type
+ checking using the arg types for this method. */
+ method_params = tree_cons (NULL_TREE, lookup_object,
+ tree_cons (NULL_TREE, selector,
+ method_params));
+ assemble_external (sender);
+ retval = build_function_call (sender, method_params);
+
+ /* Restore SENDER's return/argument types. */
+ TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
+ TREE_TYPE (TREE_TYPE (sender)) = savret;
+ return retval;
+ }
+ }
+ else
+ {
+ /* This is the portable way.
+ First call the lookup function to get a pointer to the method,
+ then cast the pointer, then call it with the method arguments. */
+ tree method;
+
+ /* Avoid trouble since we may evaluate each of these twice. */
+ object = save_expr (object);
+ selector = save_expr (selector);
+
+ lookup_object = build_c_cast (rcv_p, lookup_object);
+
+ assemble_external (sender);
+ method
+ = build_function_call (sender,
+ tree_cons (NULL_TREE, lookup_object,
+ tree_cons (NULL_TREE, selector,
+ NULL_TREE)));
+
+ /* If we have a method prototype, construct the data type this
+ method needs, and cast what we got from SENDER into a pointer
+ to that type. */
+ if (method_prototype)
+ {
+ tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
+ super_flag);
+ tree valtype = groktypename (TREE_TYPE (method_prototype));
+ tree fake_function_type = build_function_type (valtype, arglist);
+ TREE_TYPE (method) = build_pointer_type (fake_function_type);
+ }
+ else
+ TREE_TYPE (method)
+ = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
+
+ /* Pass the object to the method. */
+ assemble_external (method);
+ return build_function_call (method,
+ tree_cons (NULL_TREE, object,
+ tree_cons (NULL_TREE, selector,
+ method_params)));
+ }
+}
+
+static void
+build_protocol_reference (p)
+ tree p;
+{
+ tree decl, ident, ptype;
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
+
+ ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
+ ptype
+ = groktypename (build_tree_list (build_tree_list (NULL_TREE,
+ objc_protocol_template),
+ NULL_TREE));
+
+ if (IDENTIFIER_GLOBAL_VALUE (ident))
+ decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
+ else
+ {
+ decl = build_decl (VAR_DECL, ident, ptype);
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ TREE_USED (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+
+ make_decl_rtl (decl, 0, 1);
+ pushdecl_top_level (decl);
+ }
+
+ PROTOCOL_FORWARD_DECL (p) = decl;
+ pop_obstacks ();
+}
+
+tree
+build_protocol_expr (protoname)
+ tree protoname;
+{
+ tree expr;
+ tree p;
+
+ if (!doing_objc_thang)
+ objc_fatal ();
+
+ p = lookup_protocol (protoname);
+
+ if (!p)
+ {
+ error ("Cannot find protocol declaration for `%s'",
+ IDENTIFIER_POINTER (protoname));
+ return error_mark_node;
+ }
+
+ if (!PROTOCOL_FORWARD_DECL (p))
+ build_protocol_reference (p);
+
+ expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
+
+ TREE_TYPE (expr) = protocol_type;
+
+ return expr;
+}
+
+tree
+build_selector_expr (selnamelist)
+ tree selnamelist;
+{
+ tree selname;
+
+ if (!doing_objc_thang)
+ objc_fatal ();
+
+ /* Obtain the full selector name. */
+ if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
+ /* A unary selector. */
+ selname = selnamelist;
+ else if (TREE_CODE (selnamelist) == TREE_LIST)
+ selname = build_keyword_selector (selnamelist);
+
+ if (flag_typed_selectors)
+ return build_typed_selector_reference (selname, 0);
+ else
+ return build_selector_reference (selname);
+}
+
+tree
+build_encode_expr (type)
+ tree type;
+{
+ tree result;
+ char *string;
+
+ if (!doing_objc_thang)
+ objc_fatal ();
+
+ encode_type (type, obstack_object_size (&util_obstack),
+ OBJC_ENCODE_INLINE_DEFS);
+ obstack_1grow (&util_obstack, 0); /* null terminate string */
+ string = obstack_finish (&util_obstack);
+
+ /* Synthesize a string that represents the encoded struct/union. */
+ result = my_build_string (strlen (string) + 1, string);
+ obstack_free (&util_obstack, util_firstobj);
+ return result;
+}
+
+tree
+build_ivar_reference (id)
+ tree id;
+{
+ if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
+ {
+ /* Historically, a class method that produced objects (factory
+ method) would assign `self' to the instance that it
+ allocated. This would effectively turn the class method into
+ an instance method. Following this assignment, the instance
+ variables could be accessed. That practice, while safe,
+ violates the simple rule that a class method should not refer
+ to an instance variable. It's better to catch the cases
+ where this is done unknowingly than to support the above
+ paradigm. */
+ warning ("instance variable `%s' accessed in class method",
+ IDENTIFIER_POINTER (id));
+ TREE_TYPE (self_decl) = instance_type; /* cast */
+ }
+
+ return build_component_ref (build_indirect_ref (self_decl, "->"), id);
+}
+
+#define HASH_ALLOC_LIST_SIZE 170
+#define ATTR_ALLOC_LIST_SIZE 170
+#define SIZEHASHTABLE 257
+
+/* make positive */
+#define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
+
+static void
+hash_init ()
+{
+ nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
+ cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
+
+ if (!nst_method_hash_list || !cls_method_hash_list)
+ perror ("unable to allocate space in objc-tree.c");
+ else
+ {
+ int i;
+
+ for (i = 0; i < SIZEHASHTABLE; i++)
+ {
+ nst_method_hash_list[i] = 0;
+ cls_method_hash_list[i] = 0;
+ }
+ }
+}
+
+static void
+hash_enter (hashlist, method)
+ hash *hashlist;
+ tree method;
+{
+ static hash hash_alloc_list = 0;
+ static int hash_alloc_index = 0;
+ hash obj;
+ int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
+
+ if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
+ {
+ hash_alloc_index = 0;
+ hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
+ * HASH_ALLOC_LIST_SIZE);
+ if (! hash_alloc_list)
+ perror ("unable to allocate in objc-tree.c");
+ }
+ obj = &hash_alloc_list[hash_alloc_index++];
+ obj->list = 0;
+ obj->next = hashlist[slot];
+ obj->key = method;
+
+ hashlist[slot] = obj; /* append to front */
+}
+
+static hash
+hash_lookup (hashlist, sel_name)
+ hash *hashlist;
+ tree sel_name;
+{
+ hash target;
+
+ target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
+
+ while (target)
+ {
+ if (sel_name == METHOD_SEL_NAME (target->key))
+ return target;
+
+ target = target->next;
+ }
+ return 0;
+}
+
+static void
+hash_add_attr (entry, value)
+ hash entry;
+ tree value;
+{
+ static attr attr_alloc_list = 0;
+ static int attr_alloc_index = 0;
+ attr obj;
+
+ if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
+ {
+ attr_alloc_index = 0;
+ attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
+ * ATTR_ALLOC_LIST_SIZE);
+ if (! attr_alloc_list)
+ perror ("unable to allocate in objc-tree.c");
+ }
+ obj = &attr_alloc_list[attr_alloc_index++];
+ obj->next = entry->list;
+ obj->value = value;
+
+ entry->list = obj; /* append to front */
+}
+
+static tree
+lookup_method (mchain, method)
+ tree mchain;
+ tree method;
+{
+ tree key;
+
+ if (TREE_CODE (method) == IDENTIFIER_NODE)
+ key = method;
+ else
+ key = METHOD_SEL_NAME (method);
+
+ while (mchain)
+ {
+ if (METHOD_SEL_NAME (mchain) == key)
+ return mchain;
+ mchain = TREE_CHAIN (mchain);
+ }
+ return NULL_TREE;
+}
+
+static tree
+lookup_instance_method_static (interface, ident)
+ tree interface;
+ tree ident;
+{
+ tree inter = interface;
+ tree chain = CLASS_NST_METHODS (inter);
+ tree meth = NULL_TREE;
+
+ do
+ {
+ if ((meth = lookup_method (chain, ident)))
+ return meth;
+
+ if (CLASS_CATEGORY_LIST (inter))
+ {
+ tree category = CLASS_CATEGORY_LIST (inter);
+ chain = CLASS_NST_METHODS (category);
+
+ do
+ {
+ if ((meth = lookup_method (chain, ident)))
+ return meth;
+
+ /* Check for instance methods in protocols in categories. */
+ if (CLASS_PROTOCOL_LIST (category))
+ {
+ if ((meth = (lookup_method_in_protocol_list
+ (CLASS_PROTOCOL_LIST (category), ident, 0))))
+ return meth;
+ }
+
+ if ((category = CLASS_CATEGORY_LIST (category)))
+ chain = CLASS_NST_METHODS (category);
+ }
+ while (category);
+ }
+
+ if (CLASS_PROTOCOL_LIST (inter))
+ {
+ if ((meth = (lookup_method_in_protocol_list
+ (CLASS_PROTOCOL_LIST (inter), ident, 0))))
+ return meth;
+ }
+
+ if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
+ chain = CLASS_NST_METHODS (inter);
+ }
+ while (inter);
+
+ return meth;
+}
+
+static tree
+lookup_class_method_static (interface, ident)
+ tree interface;
+ tree ident;
+{
+ tree inter = interface;
+ tree chain = CLASS_CLS_METHODS (inter);
+ tree meth = NULL_TREE;
+ tree root_inter = NULL_TREE;
+
+ do
+ {
+ if ((meth = lookup_method (chain, ident)))
+ return meth;
+
+ if (CLASS_CATEGORY_LIST (inter))
+ {
+ tree category = CLASS_CATEGORY_LIST (inter);
+ chain = CLASS_CLS_METHODS (category);
+
+ do
+ {
+ if ((meth = lookup_method (chain, ident)))
+ return meth;
+
+ /* Check for class methods in protocols in categories. */
+ if (CLASS_PROTOCOL_LIST (category))
+ {
+ if ((meth = (lookup_method_in_protocol_list
+ (CLASS_PROTOCOL_LIST (category), ident, 1))))
+ return meth;
+ }
+
+ if ((category = CLASS_CATEGORY_LIST (category)))
+ chain = CLASS_CLS_METHODS (category);
+ }
+ while (category);
+ }
+
+ /* Check for class methods in protocols. */
+ if (CLASS_PROTOCOL_LIST (inter))
+ {
+ if ((meth = (lookup_method_in_protocol_list
+ (CLASS_PROTOCOL_LIST (inter), ident, 1))))
+ return meth;
+ }
+
+ root_inter = inter;
+ if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
+ chain = CLASS_CLS_METHODS (inter);
+ }
+ while (inter);
+
+ /* Simulate wrap around. */
+ return lookup_instance_method_static (root_inter, ident);
+}
+
+tree
+add_class_method (class, method)
+ tree class;
+ tree method;
+{
+ tree mth;
+ hash hsh;
+
+ /* We will have allocated the method parameter declarations on the
+ maybepermanent_obstack. Need to make sure they stick around! */
+ preserve_data ();
+
+ if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
+ {
+ /* put method on list in reverse order */
+ TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
+ CLASS_CLS_METHODS (class) = method;
+ }
+ else
+ {
+ if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
+ error ("duplicate definition of class method `%s'.",
+ IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
+ else
+ {
+ /* Check types; if different, complain. */
+ if (!comp_proto_with_proto (method, mth))
+ error ("duplicate declaration of class method `%s'.",
+ IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
+ }
+ }
+
+ if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
+ {
+ /* Install on a global chain. */
+ hash_enter (cls_method_hash_list, method);
+ }
+ else
+ {
+ /* Check types; if different, add to a list. */
+ if (!comp_proto_with_proto (method, hsh->key))
+ hash_add_attr (hsh, method);
+ }
+ return method;
+}
+
+tree
+add_instance_method (class, method)
+ tree class;
+ tree method;
+{
+ tree mth;
+ hash hsh;
+
+ /* We will have allocated the method parameter declarations on the
+ maybepermanent_obstack. Need to make sure they stick around! */
+ preserve_data ();
+
+ if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
+ {
+ /* Put method on list in reverse order. */
+ TREE_CHAIN (method) = CLASS_NST_METHODS (class);
+ CLASS_NST_METHODS (class) = method;
+ }
+ else
+ {
+ if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
+ error ("duplicate definition of instance method `%s'.",
+ IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
+ else
+ {
+ /* Check types; if different, complain. */
+ if (!comp_proto_with_proto (method, mth))
+ error ("duplicate declaration of instance method `%s'.",
+ IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
+ }
+ }
+
+ if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
+ {
+ /* Install on a global chain. */
+ hash_enter (nst_method_hash_list, method);
+ }
+ else
+ {
+ /* Check types; if different, add to a list. */
+ if (!comp_proto_with_proto (method, hsh->key))
+ hash_add_attr (hsh, method);
+ }
+ return method;
+}
+
+static tree
+add_class (class)
+ tree class;
+{
+ /* Put interfaces on list in reverse order. */
+ TREE_CHAIN (class) = interface_chain;
+ interface_chain = class;
+ return interface_chain;
+}
+
+static void
+add_category (class, category)
+ tree class;
+ tree category;
+{
+ /* Put categories on list in reverse order. */
+ tree cat = CLASS_CATEGORY_LIST (class);
+
+ while (cat)
+ {
+ if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
+ warning ("duplicate interface declaration for category `%s(%s)'",
+ IDENTIFIER_POINTER (CLASS_NAME (class)),
+ IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
+ cat = CLASS_CATEGORY_LIST (cat);
+ }
+
+ CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
+ CLASS_CATEGORY_LIST (class) = category;
+}
+
+/* Called after parsing each instance variable declaration. Necessary to
+ preserve typedefs and implement public/private...
+
+ PUBLIC is 1 for public, 0 for protected, and 2 for private. */
+
+tree
+add_instance_variable (class, public, declarator, declspecs, width)
+ tree class;
+ int public;
+ tree declarator;
+ tree declspecs;
+ tree width;
+{
+ tree field_decl, raw_decl;
+
+ raw_decl = build_tree_list (declspecs, declarator);
+
+ if (CLASS_RAW_IVARS (class))
+ chainon (CLASS_RAW_IVARS (class), raw_decl);
+ else
+ CLASS_RAW_IVARS (class) = raw_decl;
+
+ field_decl = grokfield (input_filename, lineno,
+ declarator, declspecs, width);
+
+ /* Overload the public attribute, it is not used for FIELD_DECLs. */
+ switch (public)
+ {
+ case 0:
+ TREE_PUBLIC (field_decl) = 0;
+ TREE_PRIVATE (field_decl) = 0;
+ TREE_PROTECTED (field_decl) = 1;
+ break;
+
+ case 1:
+ TREE_PUBLIC (field_decl) = 1;
+ TREE_PRIVATE (field_decl) = 0;
+ TREE_PROTECTED (field_decl) = 0;
+ break;
+
+ case 2:
+ TREE_PUBLIC (field_decl) = 0;
+ TREE_PRIVATE (field_decl) = 1;
+ TREE_PROTECTED (field_decl) = 0;
+ break;
+
+ }
+
+ if (CLASS_IVARS (class))
+ chainon (CLASS_IVARS (class), field_decl);
+ else
+ CLASS_IVARS (class) = field_decl;
+
+ return class;
+}
+
+tree
+is_ivar (decl_chain, ident)
+ tree decl_chain;
+ tree ident;
+{
+ for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
+ if (DECL_NAME (decl_chain) == ident)
+ return decl_chain;
+ return NULL_TREE;
+}
+
+/* True if the ivar is private and we are not in its implementation. */
+
+int
+is_private (decl)
+ tree decl;
+{
+ if (TREE_PRIVATE (decl)
+ && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
+ {
+ error ("instance variable `%s' is declared private",
+ IDENTIFIER_POINTER (DECL_NAME (decl)));
+ return 1;
+ }
+ else
+ return 0;
+}
+
+/* We have an instance variable reference;, check to see if it is public. */
+
+int
+is_public (expr, identifier)
+ tree expr;
+ tree identifier;
+{
+ tree basetype = TREE_TYPE (expr);
+ enum tree_code code = TREE_CODE (basetype);
+ tree decl;
+
+ if (code == RECORD_TYPE)
+ {
+ if (TREE_STATIC_TEMPLATE (basetype))
+ {
+ if (!lookup_interface (TYPE_NAME (basetype)))
+ {
+ error ("Cannot find interface declaration for `%s'",
+ IDENTIFIER_POINTER (TYPE_NAME (basetype)));
+ return 0;
+ }
+
+ if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
+ {
+ if (TREE_PUBLIC (decl))
+ return 1;
+
+ /* Important difference between the Stepstone translator:
+ all instance variables should be public within the context
+ of the implementation. */
+ if (implementation_context
+ && (((TREE_CODE (implementation_context)
+ == CLASS_IMPLEMENTATION_TYPE)
+ || (TREE_CODE (implementation_context)
+ == CATEGORY_IMPLEMENTATION_TYPE))
+ && (CLASS_NAME (implementation_context)
+ == TYPE_NAME (basetype))))
+ return ! is_private (decl);
+
+ error ("instance variable `%s' is declared %s",
+ IDENTIFIER_POINTER (identifier),
+ TREE_PRIVATE (decl) ? "private" : "protected");
+ return 0;
+ }
+ }
+
+ else if (implementation_context && (basetype == objc_object_reference))
+ {
+ TREE_TYPE (expr) = uprivate_record;
+ warning ("static access to object of type `id'");
+ }
+ }
+
+ return 1;
+}
+
+/* Implement @defs (<classname>) within struct bodies. */
+
+tree
+get_class_ivars (interface)
+ tree interface;
+{
+ if (!doing_objc_thang)
+ objc_fatal ();
+
+ return build_ivar_chain (interface, 1);
+}
+
+/* Make sure all entries in CHAIN are also in LIST. */
+
+static int
+check_methods (chain, list, mtype)
+ tree chain;
+ tree list;
+ int mtype;
+{
+ int first = 1;
+
+ while (chain)
+ {
+ if (!lookup_method (list, chain))
+ {
+ if (first)
+ {
+ if (TREE_CODE (implementation_context)
+ == CLASS_IMPLEMENTATION_TYPE)
+ warning ("incomplete implementation of class `%s'",
+ IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
+ else if (TREE_CODE (implementation_context)
+ == CATEGORY_IMPLEMENTATION_TYPE)
+ warning ("incomplete implementation of category `%s'",
+ IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
+ first = 0;
+ }
+
+ warning ("method definition for `%c%s' not found",
+ mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
+ }
+
+ chain = TREE_CHAIN (chain);
+ }
+
+ return first;
+}
+
+static int
+conforms_to_protocol (class, protocol)
+ tree class;
+ tree protocol;
+{
+ while (protocol)
+ {
+ tree p = CLASS_PROTOCOL_LIST (class);
+
+ while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
+ p = TREE_CHAIN (p);
+
+ if (!p)
+ {
+ tree super = (CLASS_SUPER_NAME (class)
+ ? lookup_interface (CLASS_SUPER_NAME (class))
+ : NULL_TREE);
+ int tmp = super ? conforms_to_protocol (super, protocol) : 0;
+ if (!tmp)
+ return 0;
+ }
+
+ protocol = TREE_CHAIN (protocol);
+ }
+
+ return 1;
+}
+
+/* Make sure all methods in CHAIN are accessible as MTYPE methods in
+ CONTEXT. This is one of two mechanisms to check protocol integrity. */
+
+static int
+check_methods_accessible (chain, context, mtype)
+ tree chain;
+ tree context;
+ int mtype;
+{
+ int first = 1;
+ tree list;
+ tree base_context = context;
+
+ while (chain)
+ {
+ context = base_context;
+ while (context)
+ {
+ if (mtype == '+')
+ list = CLASS_CLS_METHODS (context);
+ else
+ list = CLASS_NST_METHODS (context);
+
+ if (lookup_method (list, chain))
+ break;
+
+ else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
+ || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
+ context = (CLASS_SUPER_NAME (context)
+ ? lookup_interface (CLASS_SUPER_NAME (context))
+ : NULL_TREE);
+
+ else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
+ || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
+ context = (CLASS_NAME (context)
+ ? lookup_interface (CLASS_NAME (context))
+ : NULL_TREE);
+ else
+ abort ();
+ }
+
+ if (context == NULL_TREE)
+ {
+ if (first)
+ {
+ if (TREE_CODE (implementation_context)
+ == CLASS_IMPLEMENTATION_TYPE)
+ warning ("incomplete implementation of class `%s'",
+ IDENTIFIER_POINTER
+ (CLASS_NAME (implementation_context)));
+ else if (TREE_CODE (implementation_context)
+ == CATEGORY_IMPLEMENTATION_TYPE)
+ warning ("incomplete implementation of category `%s'",
+ IDENTIFIER_POINTER
+ (CLASS_SUPER_NAME (implementation_context)));
+ first = 0;
+ }
+ warning ("method definition for `%c%s' not found",
+ mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
+ }
+
+ chain = TREE_CHAIN (chain); /* next method... */
+ }
+ return first;
+}
+
+static void
+check_protocols (proto_list, type, name)
+ tree proto_list;
+ char *type;
+ char *name;
+{
+ for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
+ {
+ tree p = TREE_VALUE (proto_list);
+
+ if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
+ {
+ int f1, f2;
+
+ /* Ensure that all protocols have bodies. */
+ if (flag_warn_protocol) {
+ f1 = check_methods (PROTOCOL_CLS_METHODS (p),
+ CLASS_CLS_METHODS (implementation_context),
+ '+');
+ f2 = check_methods (PROTOCOL_NST_METHODS (p),
+ CLASS_NST_METHODS (implementation_context),
+ '-');
+ } else {
+ f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
+ implementation_context,
+ '+');
+ f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
+ implementation_context,
+ '-');
+ }
+
+ if (!f1 || !f2)
+ warning ("%s `%s' does not fully implement the `%s' protocol",
+ type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
+
+ }
+ else
+ ; /* An identifier if we could not find a protocol. */
+
+ /* Check protocols recursively. */
+ if (PROTOCOL_LIST (p))
+ {
+ tree super_class
+ = lookup_interface (CLASS_SUPER_NAME (implementation_template));
+ if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
+ check_protocols (PROTOCOL_LIST (p), type, name);
+ }
+ }
+}
+
+/* Make sure that the class CLASS_NAME is defined
+ CODE says which kind of thing CLASS_NAME ought to be.
+ It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
+ CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
+
+ If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
+ whose matching pop is in continue_class. */
+
+tree
+start_class (code, class_name, super_name, protocol_list)
+ enum tree_code code;
+ tree class_name;
+ tree super_name;
+ tree protocol_list;
+{
+ tree class, decl;
+
+ if (code == CLASS_INTERFACE_TYPE)
+ {
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+ }
+
+ if (!doing_objc_thang)
+ objc_fatal ();
+
+ class = make_node (code);
+ TYPE_BINFO (class) = make_tree_vec (5);
+
+ CLASS_NAME (class) = class_name;
+ CLASS_SUPER_NAME (class) = super_name;
+ CLASS_CLS_METHODS (class) = NULL_TREE;
+
+ if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
+ {
+ error ("`%s' redeclared as different kind of symbol",
+ IDENTIFIER_POINTER (class_name));
+ error_with_decl (decl, "previous declaration of `%s'");
+ }
+
+ if (code == CLASS_IMPLEMENTATION_TYPE)
+ {
+ {
+ static tree implemented_classes = 0;
+ tree chain = implemented_classes;
+ for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
+ if (TREE_VALUE (chain) == class_name)
+ {
+ error ("reimplementation of class `%s'",
+ IDENTIFIER_POINTER (class_name));
+ return error_mark_node;
+ }
+ implemented_classes = perm_tree_cons (NULL_TREE, class_name,
+ implemented_classes);
+ }
+
+ /* Pre-build the following entities - for speed/convenience. */
+ if (!self_id)
+ self_id = get_identifier ("self");
+ if (!ucmd_id)
+ ucmd_id = get_identifier ("_cmd");
+ if (!unused_list)
+ unused_list
+ = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
+ if (!objc_super_template)
+ objc_super_template = build_super_template ();
+
+ /* Reset for multiple classes per file. */
+ method_slot = 0;
+
+ implementation_context = class;
+
+ /* Lookup the interface for this implementation. */
+
+ if (!(implementation_template = lookup_interface (class_name)))
+ {
+ warning ("Cannot find interface declaration for `%s'",
+ IDENTIFIER_POINTER (class_name));
+ add_class (implementation_template = implementation_context);
+ }
+
+ /* If a super class has been specified in the implementation,
+ insure it conforms to the one specified in the interface. */
+
+ if (super_name
+ && (super_name != CLASS_SUPER_NAME (implementation_template)))
+ {
+ tree previous_name = CLASS_SUPER_NAME (implementation_template);
+ char *name = previous_name ? IDENTIFIER_POINTER (previous_name) : "";
+ error ("conflicting super class name `%s'",
+ IDENTIFIER_POINTER (super_name));
+ error ("previous declaration of `%s'", name);
+ }
+
+ else if (! super_name)
+ {
+ CLASS_SUPER_NAME (implementation_context)
+ = CLASS_SUPER_NAME (implementation_template);
+ }
+ }
+
+ else if (code == CLASS_INTERFACE_TYPE)
+ {
+ if (lookup_interface (class_name))
+ warning ("duplicate interface declaration for class `%s'",
+ IDENTIFIER_POINTER (class_name));
+ else
+ add_class (class);
+
+ if (protocol_list)
+ CLASS_PROTOCOL_LIST (class)
+ = lookup_and_install_protocols (protocol_list);
+ }
+
+ else if (code == CATEGORY_INTERFACE_TYPE)
+ {
+ tree class_category_is_assoc_with;
+
+ /* For a category, class_name is really the name of the class that
+ the following set of methods will be associated with. We must
+ find the interface so that can derive the objects template. */
+
+ if (!(class_category_is_assoc_with = lookup_interface (class_name)))
+ {
+ error ("Cannot find interface declaration for `%s'",
+ IDENTIFIER_POINTER (class_name));
+ exit (FATAL_EXIT_CODE);
+ }
+ else
+ add_category (class_category_is_assoc_with, class);
+
+ if (protocol_list)
+ CLASS_PROTOCOL_LIST (class)
+ = lookup_and_install_protocols (protocol_list);
+ }
+
+ else if (code == CATEGORY_IMPLEMENTATION_TYPE)
+ {
+ /* Pre-build the following entities for speed/convenience. */
+ if (!self_id)
+ self_id = get_identifier ("self");
+ if (!ucmd_id)
+ ucmd_id = get_identifier ("_cmd");
+ if (!unused_list)
+ unused_list
+ = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
+ if (!objc_super_template)
+ objc_super_template = build_super_template ();
+
+ /* Reset for multiple classes per file. */
+ method_slot = 0;
+
+ implementation_context = class;
+
+ /* For a category, class_name is really the name of the class that
+ the following set of methods will be associated with. We must
+ find the interface so that can derive the objects template. */
+
+ if (!(implementation_template = lookup_interface (class_name)))
+ {
+ error ("Cannot find interface declaration for `%s'",
+ IDENTIFIER_POINTER (class_name));
+ exit (FATAL_EXIT_CODE);
+ }
+ }
+ return class;
+}
+
+tree
+continue_class (class)
+ tree class;
+{
+ if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
+ || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
+ {
+ struct imp_entry *imp_entry;
+ tree ivar_context;
+
+ /* Check consistency of the instance variables. */
+
+ if (CLASS_IVARS (class))
+ check_ivars (implementation_template, class);
+
+ /* code generation */
+
+ ivar_context = build_private_template (implementation_template);
+
+ if (!objc_class_template)
+ build_class_template ();
+
+ if (!(imp_entry
+ = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
+ perror ("unable to allocate in objc-tree.c");
+
+ imp_entry->next = imp_list;
+ imp_entry->imp_context = class;
+ imp_entry->imp_template = implementation_template;
+
+ synth_forward_declarations ();
+ imp_entry->class_decl = UOBJC_CLASS_decl;
+ imp_entry->meta_decl = UOBJC_METACLASS_decl;
+
+ /* Append to front and increment count. */
+ imp_list = imp_entry;
+ if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
+ imp_count++;
+ else
+ cat_count++;
+
+ return ivar_context;
+ }
+
+ else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
+ {
+ tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
+
+ if (!TYPE_FIELDS (record))
+ {
+ finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
+ CLASS_STATIC_TEMPLATE (class) = record;
+
+ /* Mark this record as a class template for static typing. */
+ TREE_STATIC_TEMPLATE (record) = 1;
+ }
+
+ return NULL_TREE;
+ }
+
+ else
+ return error_mark_node;
+}
+
+/* This is called once we see the "@end" in an interface/implementation. */
+
+void
+finish_class (class)
+ tree class;
+{
+ if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
+ {
+ /* All code generation is done in finish_objc. */
+
+ if (implementation_template != implementation_context)
+ {
+ /* Ensure that all method listed in the interface contain bodies. */
+ check_methods (CLASS_CLS_METHODS (implementation_template),
+ CLASS_CLS_METHODS (implementation_context), '+');
+ check_methods (CLASS_NST_METHODS (implementation_template),
+ CLASS_NST_METHODS (implementation_context), '-');
+
+ if (CLASS_PROTOCOL_LIST (implementation_template))
+ check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
+ "class",
+ IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
+ }
+ }
+
+ else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
+ {
+ tree category = CLASS_CATEGORY_LIST (implementation_template);
+
+ /* Find the category interface from the class it is associated with. */
+ while (category)
+ {
+ if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
+ break;
+ category = CLASS_CATEGORY_LIST (category);
+ }
+
+ if (category)
+ {
+ /* Ensure all method listed in the interface contain bodies. */
+ check_methods (CLASS_CLS_METHODS (category),
+ CLASS_CLS_METHODS (implementation_context), '+');
+ check_methods (CLASS_NST_METHODS (category),
+ CLASS_NST_METHODS (implementation_context), '-');
+
+ if (CLASS_PROTOCOL_LIST (category))
+ check_protocols (CLASS_PROTOCOL_LIST (category),
+ "category",
+ IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
+ }
+ }
+
+ else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
+ {
+ tree decl_specs;
+ char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
+ char *string = (char *) alloca (strlen (class_name) + 3);
+
+ /* extern struct objc_object *_<my_name>; */
+
+ sprintf (string, "_%s", class_name);
+
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
+ decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
+ define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
+ decl_specs);
+ }
+}
+
+static tree
+add_protocol (protocol)
+ tree protocol;
+{
+ /* Put protocol on list in reverse order. */
+ TREE_CHAIN (protocol) = protocol_chain;
+ protocol_chain = protocol;
+ return protocol_chain;
+}
+
+static tree
+lookup_protocol (ident)
+ tree ident;
+{
+ tree chain;
+
+ for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
+ {
+ if (ident == PROTOCOL_NAME (chain))
+ return chain;
+ }
+
+ return NULL_TREE;
+}
+
+tree
+start_protocol (code, name, list)
+ enum tree_code code;
+ tree name;
+ tree list;
+{
+ tree protocol;
+
+ if (!doing_objc_thang)
+ objc_fatal ();
+
+ /* This is as good a place as any. Need to invoke push_tag_toplevel. */
+ if (!objc_protocol_template)
+ objc_protocol_template = build_protocol_template ();
+
+ protocol = make_node (code);
+ TYPE_BINFO (protocol) = make_tree_vec (2);
+
+ PROTOCOL_NAME (protocol) = name;
+ PROTOCOL_LIST (protocol) = list;
+
+ lookup_and_install_protocols (list);
+
+ if (lookup_protocol (name))
+ warning ("duplicate declaration for protocol `%s'",
+ IDENTIFIER_POINTER (name));
+ else
+ add_protocol (protocol);
+
+ PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
+
+ return protocol;
+}
+
+void
+finish_protocol (protocol)
+ tree protocol;
+{
+}
+
+
+/* "Encode" a data type into a string, which grows in util_obstack.
+ ??? What is the FORMAT? Someone please document this! */
+
+static void
+encode_type_qualifiers (declspecs)
+ tree declspecs;
+{
+ tree spec;
+
+ for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
+ {
+ if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
+ obstack_1grow (&util_obstack, 'r');
+ else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
+ obstack_1grow (&util_obstack, 'n');
+ else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
+ obstack_1grow (&util_obstack, 'N');
+ else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
+ obstack_1grow (&util_obstack, 'o');
+ else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
+ obstack_1grow (&util_obstack, 'O');
+ else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
+ obstack_1grow (&util_obstack, 'V');
+ }
+}
+
+/* Encode a pointer type. */
+
+static void
+encode_pointer (type, curtype, format)
+ tree type;
+ int curtype;
+ int format;
+{
+ tree pointer_to = TREE_TYPE (type);
+
+ if (TREE_CODE (pointer_to) == RECORD_TYPE)
+ {
+ if (TYPE_NAME (pointer_to)
+ && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
+ {
+ char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
+
+ if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
+ {
+ obstack_1grow (&util_obstack, '@');
+ return;
+ }
+ else if (TREE_STATIC_TEMPLATE (pointer_to))
+ {
+ if (generating_instance_variables)
+ {
+ obstack_1grow (&util_obstack, '@');
+ obstack_1grow (&util_obstack, '"');
+ obstack_grow (&util_obstack, name, strlen (name));
+ obstack_1grow (&util_obstack, '"');
+ return;
+ }
+ else
+ {
+ obstack_1grow (&util_obstack, '@');
+ return;
+ }
+ }
+ else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
+ {
+ obstack_1grow (&util_obstack, '#');
+ return;
+ }
+#ifndef OBJC_INT_SELECTORS
+ else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
+ {
+ obstack_1grow (&util_obstack, ':');
+ return;
+ }
+#endif /* OBJC_INT_SELECTORS */
+ }
+ }
+ else if (TREE_CODE (pointer_to) == INTEGER_TYPE
+ && TYPE_MODE (pointer_to) == QImode)
+ {
+ obstack_1grow (&util_obstack, '*');
+ return;
+ }
+
+ /* We have a type that does not get special treatment. */
+
+ /* NeXT extension */
+ obstack_1grow (&util_obstack, '^');
+ encode_type (pointer_to, curtype, format);
+}
+
+static void
+encode_array (type, curtype, format)
+ tree type;
+ int curtype;
+ int format;
+{
+ tree an_int_cst = TYPE_SIZE (type);
+ tree array_of = TREE_TYPE (type);
+ char buffer[40];
+
+ /* An incomplete array is treated like a pointer. */
+ if (an_int_cst == NULL)
+ {
+ encode_pointer (type, curtype, format);
+ return;
+ }
+
+ sprintf (buffer, "[%d",
+ (TREE_INT_CST_LOW (an_int_cst)
+ / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
+
+ obstack_grow (&util_obstack, buffer, strlen (buffer));
+ encode_type (array_of, curtype, format);
+ obstack_1grow (&util_obstack, ']');
+ return;
+}
+
+static void
+encode_aggregate_within (type, curtype, format, left, right)
+ tree type;
+ int curtype;
+ int format;
+ char left;
+ char right;
+{
+ if (obstack_object_size (&util_obstack) > 0
+ && *(obstack_next_free (&util_obstack) - 1) == '^')
+ {
+ tree name = TYPE_NAME (type);
+
+ /* we have a reference; this is a NeXT extension. */
+
+ if (obstack_object_size (&util_obstack) - curtype == 1
+ && format == OBJC_ENCODE_INLINE_DEFS)
+ {
+ /* Output format of struct for first level only. */
+ tree fields = TYPE_FIELDS (type);
+
+ if (name && TREE_CODE (name) == IDENTIFIER_NODE)
+ {
+ obstack_1grow (&util_obstack, left);
+ obstack_grow (&util_obstack,
+ IDENTIFIER_POINTER (name),
+ strlen (IDENTIFIER_POINTER (name)));
+ obstack_1grow (&util_obstack, '=');
+ }
+ else
+ {
+ obstack_1grow (&util_obstack, left);
+ obstack_grow (&util_obstack, "?=", 2);
+ }
+
+ for ( ; fields; fields = TREE_CHAIN (fields))
+ encode_field_decl (fields, curtype, format);
+
+ obstack_1grow (&util_obstack, right);
+ }
+
+ else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
+ {
+ obstack_1grow (&util_obstack, left);
+ obstack_grow (&util_obstack,
+ IDENTIFIER_POINTER (name),
+ strlen (IDENTIFIER_POINTER (name)));
+ obstack_1grow (&util_obstack, right);
+ }
+
+ else
+ {
+ /* We have an untagged structure or a typedef. */
+ obstack_1grow (&util_obstack, left);
+ obstack_1grow (&util_obstack, '?');
+ obstack_1grow (&util_obstack, right);
+ }
+ }
+
+ else
+ {
+ tree name = TYPE_NAME (type);
+ tree fields = TYPE_FIELDS (type);
+
+ if (format == OBJC_ENCODE_INLINE_DEFS
+ || generating_instance_variables)
+ {
+ obstack_1grow (&util_obstack, left);
+ if (name && TREE_CODE (name) == IDENTIFIER_NODE)
+ obstack_grow (&util_obstack,
+ IDENTIFIER_POINTER (name),
+ strlen (IDENTIFIER_POINTER (name)));
+ else
+ obstack_1grow (&util_obstack, '?');
+
+ obstack_1grow (&util_obstack, '=');
+
+ for (; fields; fields = TREE_CHAIN (fields))
+ {
+ if (generating_instance_variables)
+ {
+ tree fname = DECL_NAME (fields);
+
+ obstack_1grow (&util_obstack, '"');
+ if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
+ {
+ obstack_grow (&util_obstack,
+ IDENTIFIER_POINTER (fname),
+ strlen (IDENTIFIER_POINTER (fname)));
+ }
+
+ obstack_1grow (&util_obstack, '"');
+ }
+
+ encode_field_decl (fields, curtype, format);
+ }
+
+ obstack_1grow (&util_obstack, right);
+ }
+
+ else
+ {
+ obstack_1grow (&util_obstack, left);
+ if (name && TREE_CODE (name) == IDENTIFIER_NODE)
+ obstack_grow (&util_obstack,
+ IDENTIFIER_POINTER (name),
+ strlen (IDENTIFIER_POINTER (name)));
+ else
+ /* We have an untagged structure or a typedef. */
+ obstack_1grow (&util_obstack, '?');
+
+ obstack_1grow (&util_obstack, right);
+ }
+ }
+}
+
+static void
+encode_aggregate (type, curtype, format)
+ tree type;
+ int curtype;
+ int format;
+{
+ enum tree_code code = TREE_CODE (type);
+
+ switch (code)
+ {
+ case RECORD_TYPE:
+ {
+ encode_aggregate_within(type, curtype, format, '{', '}');
+ break;
+ }
+ case UNION_TYPE:
+ {
+ encode_aggregate_within(type, curtype, format, '(', ')');
+ break;
+ }
+
+ case ENUMERAL_TYPE:
+ obstack_1grow (&util_obstack, 'i');
+ break;
+ }
+}
+
+/* Support bitfields. The current version of Objective-C does not support
+ them. The string will consist of one or more "b:n"'s where n is an
+ integer describing the width of the bitfield. Currently, classes in
+ the kit implement a method "-(char *)describeBitfieldStruct:" that
+ simulates this. If they do not implement this method, the archiver
+ assumes the bitfield is 16 bits wide (padded if necessary) and packed
+ according to the GNU compiler. After looking at the "kit", it appears
+ that all classes currently rely on this default behavior, rather than
+ hand generating this string (which is tedious). */
+
+static void
+encode_bitfield (width, format)
+ int width;
+ int format;
+{
+ char buffer[40];
+ sprintf (buffer, "b%d", width);
+ obstack_grow (&util_obstack, buffer, strlen (buffer));
+}
+
+/* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
+
+static void
+encode_type (type, curtype, format)
+ tree type;
+ int curtype;
+ int format;
+{
+ enum tree_code code = TREE_CODE (type);
+
+ if (code == INTEGER_TYPE)
+ {
+ if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
+ && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
+ {
+ /* Unsigned integer types. */
+
+ if (TYPE_MODE (type) == QImode)
+ obstack_1grow (&util_obstack, 'C');
+ else if (TYPE_MODE (type) == HImode)
+ obstack_1grow (&util_obstack, 'S');
+ else if (TYPE_MODE (type) == SImode)
+ {
+ if (type == long_unsigned_type_node)
+ obstack_1grow (&util_obstack, 'L');
+ else
+ obstack_1grow (&util_obstack, 'I');
+ }
+ else if (TYPE_MODE (type) == DImode)
+ obstack_1grow (&util_obstack, 'Q');
+ }
+
+ else
+ /* Signed integer types. */
+ {
+ if (TYPE_MODE (type) == QImode)
+ obstack_1grow (&util_obstack, 'c');
+ else if (TYPE_MODE (type) == HImode)
+ obstack_1grow (&util_obstack, 's');
+ else if (TYPE_MODE (type) == SImode)
+ {
+ if (type == long_integer_type_node)
+ obstack_1grow (&util_obstack, 'l');
+ else
+ obstack_1grow (&util_obstack, 'i');
+ }
+
+ else if (TYPE_MODE (type) == DImode)
+ obstack_1grow (&util_obstack, 'q');
+ }
+ }
+
+ else if (code == REAL_TYPE)
+ {
+ /* Floating point types. */
+
+ if (TYPE_MODE (type) == SFmode)
+ obstack_1grow (&util_obstack, 'f');
+ else if (TYPE_MODE (type) == DFmode
+ || TYPE_MODE (type) == TFmode)
+ obstack_1grow (&util_obstack, 'd');
+ }
+
+ else if (code == VOID_TYPE)
+ obstack_1grow (&util_obstack, 'v');
+
+ else if (code == ARRAY_TYPE)
+ encode_array (type, curtype, format);
+
+ else if (code == POINTER_TYPE)
+ encode_pointer (type, curtype, format);
+
+ else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
+ encode_aggregate (type, curtype, format);
+
+ else if (code == FUNCTION_TYPE) /* '?' */
+ obstack_1grow (&util_obstack, '?');
+}
+
+static void
+encode_field_decl (field_decl, curtype, format)
+ tree field_decl;
+ int curtype;
+ int format;
+{
+ tree type;
+
+ /* If this field is obviously a bitfield, or is a bitfield that has been
+ clobbered to look like a ordinary integer mode, go ahead and generate
+ the bitfield typing information. */
+ type = TREE_TYPE (field_decl);
+ if (DECL_BIT_FIELD (field_decl))
+ encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
+ else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
+ && DECL_FIELD_SIZE (field_decl)
+ && TYPE_MODE (type) > DECL_MODE (field_decl))
+ encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
+ else
+ encode_type (TREE_TYPE (field_decl), curtype, format);
+}
+
+static tree
+expr_last (complex_expr)
+ tree complex_expr;
+{
+ tree next;
+
+ if (complex_expr)
+ while ((next = TREE_OPERAND (complex_expr, 0)))
+ complex_expr = next;
+
+ return complex_expr;
+}
+
+/* The selector of the current method,
+ or NULL if we aren't compiling a method. */
+
+tree
+maybe_objc_method_name (decl)
+ tree decl;
+{
+ if (method_context)
+ return METHOD_SEL_NAME (method_context);
+ else
+ return 0;
+}
+
+/* Transform a method definition into a function definition as follows:
+ - synthesize the first two arguments, "self" and "_cmd". */
+
+void
+start_method_def (method)
+ tree method;
+{
+ tree decl_specs;
+
+ /* Required to implement _msgSuper. */
+ method_context = method;
+ UOBJC_SUPER_decl = NULL_TREE;
+
+ /* Must be called BEFORE start_function. */
+ pushlevel (0);
+
+ /* Generate prototype declarations for arguments..."new-style". */
+
+ if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
+ decl_specs = build_tree_list (NULL_TREE, uprivate_record);
+ else
+ /* Really a `struct objc_class *'. However, we allow people to
+ assign to self, which changes its type midstream. */
+ decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
+
+ push_parm_decl (build_tree_list
+ (build_tree_list (decl_specs,
+ build1 (INDIRECT_REF, NULL_TREE, self_id)),
+ build_tree_list (unused_list, NULL_TREE)));
+
+#ifdef OBJC_INT_SELECTORS
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]);
+ decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
+ push_parm_decl (build_tree_list (build_tree_list (decl_specs, ucmd_id),
+ build_tree_list (unused_list, NULL_TREE)));
+#else /* not OBJC_INT_SELECTORS */
+ decl_specs = build_tree_list (NULL_TREE,
+ xref_tag (RECORD_TYPE,
+ get_identifier (TAG_SELECTOR)));
+ push_parm_decl (build_tree_list
+ (build_tree_list (decl_specs,
+ build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
+ build_tree_list (unused_list, NULL_TREE)));
+#endif /* not OBJC_INT_SELECTORS */
+
+ /* Generate argument declarations if a keyword_decl. */
+ if (METHOD_SEL_ARGS (method))
+ {
+ tree arglist = METHOD_SEL_ARGS (method);
+ do
+ {
+ tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
+ tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
+
+ if (arg_decl)
+ {
+ tree last_expr = expr_last (arg_decl);
+
+ /* Unite the abstract decl with its name. */
+ TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
+ push_parm_decl (build_tree_list
+ (build_tree_list (arg_spec, arg_decl),
+ build_tree_list (NULL_TREE, NULL_TREE)));
+
+ /* Unhook: restore the abstract declarator. */
+ TREE_OPERAND (last_expr, 0) = NULL_TREE;
+ }
+
+ else
+ push_parm_decl (build_tree_list
+ (build_tree_list (arg_spec,
+ KEYWORD_ARG_NAME (arglist)),
+ build_tree_list (NULL_TREE, NULL_TREE)));
+
+ arglist = TREE_CHAIN (arglist);
+ }
+ while (arglist);
+ }
+
+ if (METHOD_ADD_ARGS (method) > (tree)1)
+ {
+ /* We have a variable length selector - in "prototype" format. */
+ tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
+ while (akey)
+ {
+ /* This must be done prior to calling pushdecl. pushdecl is
+ going to change our chain on us. */
+ tree nextkey = TREE_CHAIN (akey);
+ pushdecl (akey);
+ akey = nextkey;
+ }
+ }
+}
+
+static void
+warn_with_method (message, mtype, method)
+ char *message;
+ int mtype;
+ tree method;
+{
+ if (count_error (1) == 0)
+ return;
+
+ report_error_function (DECL_SOURCE_FILE (method));
+
+ fprintf (stderr, "%s:%d: warning: ",
+ DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
+ bzero (errbuf, BUFSIZE);
+ fprintf (stderr, "%s `%c%s'\n",
+ message, mtype, gen_method_decl (method, errbuf));
+}
+
+/* Return 1 if METHOD is consistent with PROTO. */
+
+static int
+comp_method_with_proto (method, proto)
+ tree method, proto;
+{
+ static tree function_type = 0;
+
+ /* Create a function_type node once. */
+ if (!function_type)
+ {
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+ function_type = make_node (FUNCTION_TYPE);
+ pop_obstacks ();
+ }
+
+ /* Install argument types - normally set by build_function_type. */
+ TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
+
+ /* install return type */
+ TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
+
+ return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
+}
+
+/* Return 1 if PROTO1 is consistent with PROTO2. */
+
+static int
+comp_proto_with_proto (proto1, proto2)
+ tree proto1, proto2;
+{
+ static tree function_type1 = 0, function_type2 = 0;
+
+ /* Create a couple function_type node's once. */
+ if (!function_type1)
+ {
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+ function_type1 = make_node (FUNCTION_TYPE);
+ function_type2 = make_node (FUNCTION_TYPE);
+ pop_obstacks ();
+ }
+
+ /* Install argument types; normally set by build_function_type. */
+ TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
+ TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
+
+ /* Install return type. */
+ TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
+ TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
+
+ return comptypes (function_type1, function_type2);
+}
+
+/* - Generate an identifier for the function. the format is "_n_cls",
+ where 1 <= n <= nMethods, and cls is the name the implementation we
+ are processing.
+ - Install the return type from the method declaration.
+ - If we have a prototype, check for type consistency. */
+
+static void
+really_start_method (method, parmlist)
+ tree method, parmlist;
+{
+ tree sc_spec, ret_spec, ret_decl, decl_specs;
+ tree method_decl, method_id;
+ char *buf, *sel_name, *class_name, *cat_name;
+
+ /* Synth the storage class & assemble the return type. */
+ sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
+ ret_spec = TREE_PURPOSE (TREE_TYPE (method));
+ decl_specs = chainon (sc_spec, ret_spec);
+
+ sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
+ class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
+ cat_name = ((TREE_CODE (implementation_context)
+ == CLASS_IMPLEMENTATION_TYPE)
+ ? NULL
+ : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
+ method_slot++;
+
+ /* Make sure this is big enough for any plausible method label. */
+ buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
+ + (cat_name ? strlen (cat_name) : 0));
+
+ OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
+ class_name, cat_name, sel_name, method_slot);
+
+ method_id = get_identifier (buf);
+
+ method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
+
+ /* Check the declarator portion of the return type for the method. */
+ if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
+ {
+ /* Unite the complex decl (specified in the abstract decl) with the
+ function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
+ tree save_expr = expr_last (ret_decl);
+
+ TREE_OPERAND (save_expr, 0) = method_decl;
+ method_decl = ret_decl;
+
+ /* Fool the parser into thinking it is starting a function. */
+ start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0);
+
+ /* Unhook: this has the effect of restoring the abstract declarator. */
+ TREE_OPERAND (save_expr, 0) = NULL_TREE;
+ }
+
+ else
+ {
+ TREE_VALUE (TREE_TYPE (method)) = method_decl;
+
+ /* Fool the parser into thinking it is starting a function. */
+ start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0);
+
+ /* Unhook: this has the effect of restoring the abstract declarator. */
+ TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
+ }
+
+ METHOD_DEFINITION (method) = current_function_decl;
+
+ if (implementation_template != implementation_context)
+ {
+ tree proto;
+
+ if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
+ proto = lookup_instance_method_static (implementation_template,
+ METHOD_SEL_NAME (method));
+ else
+ proto = lookup_class_method_static (implementation_template,
+ METHOD_SEL_NAME (method));
+
+ if (proto && ! comp_method_with_proto (method, proto))
+ {
+ char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
+
+ warn_with_method ("conflicting types for", type, method);
+ warn_with_method ("previous declaration of", type, proto);
+ }
+ }
+}
+
+/* The following routine is always called...this "architecture" is to
+ accommodate "old-style" variable length selectors.
+
+ - a:a b:b // prototype ; id c; id d; // old-style. */
+
+void
+continue_method_def ()
+{
+ tree parmlist;
+
+ if (METHOD_ADD_ARGS (method_context) == (tree)1)
+ /* We have a `, ...' immediately following the selector. */
+ parmlist = get_parm_info (0);
+ else
+ parmlist = get_parm_info (1); /* place a `void_at_end' */
+
+ /* Set self_decl from the first argument...this global is used by
+ build_ivar_reference calling build_indirect_ref. */
+ self_decl = TREE_PURPOSE (parmlist);
+
+ poplevel (0, 0, 0);
+ really_start_method (method_context, parmlist);
+ store_parm_decls ();
+}
+
+/* Called by the parser, from the `pushlevel' production. */
+
+void
+add_objc_decls ()
+{
+ if (!UOBJC_SUPER_decl)
+ {
+ UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
+ build_tree_list (NULL_TREE,
+ objc_super_template),
+ 0, NULL_TREE, NULL_TREE);
+
+ finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
+
+ /* This prevents `unused variable' warnings when compiling with -Wall. */
+ TREE_USED (UOBJC_SUPER_decl) = 1;
+ DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
+ }
+}
+
+/* _n_Method (id self, SEL sel, ...)
+ {
+ struct objc_super _S;
+ _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
+ } */
+
+tree
+get_super_receiver ()
+{
+ if (method_context)
+ {
+ tree super_expr, super_expr_list;
+
+ /* Set receiver to self. */
+ super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
+ super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
+ super_expr_list = build_tree_list (NULL_TREE, super_expr);
+
+ /* Set class to begin searching. */
+ super_expr = build_component_ref (UOBJC_SUPER_decl,
+ get_identifier ("class"));
+
+ if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
+ {
+ /* [_cls, __cls]Super are "pre-built" in
+ synth_forward_declarations. */
+
+ super_expr = build_modify_expr (super_expr, NOP_EXPR,
+ ((TREE_CODE (method_context)
+ == INSTANCE_METHOD_DECL)
+ ? ucls_super_ref
+ : uucls_super_ref));
+ }
+
+ else
+ /* We have a category. */
+ {
+ tree super_name = CLASS_SUPER_NAME (implementation_template);
+ tree super_class;
+
+ if (!super_name)
+ {
+ error ("no super class declared in interface for `%s'",
+ IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
+ return error_mark_node;
+ }
+
+ if (flag_next_runtime)
+ {
+ super_class = get_class_reference (super_name);
+ if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
+ super_class
+ = build_component_ref (build_indirect_ref (super_class, "->"),
+ get_identifier ("isa"));
+ }
+ else
+ {
+ add_class_reference (super_name);
+ super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
+ ? objc_get_class_decl : objc_get_meta_class_decl);
+ assemble_external (super_class);
+ super_class
+ = build_function_call
+ (super_class,
+ build_tree_list
+ (NULL_TREE,
+ my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
+ IDENTIFIER_POINTER (super_name))));
+ }
+
+ TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
+ super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
+ }
+
+ chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
+
+ super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
+ chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
+
+ return build_compound_expr (super_expr_list);
+ }
+ else
+ {
+ error ("[super ...] must appear in a method context");
+ return error_mark_node;
+ }
+}
+
+static tree
+encode_method_def (func_decl)
+ tree func_decl;
+{
+ tree parms;
+ int stack_size;
+ int max_parm_end = 0;
+ char buffer[40];
+ tree result;
+
+ /* Return type. */
+ encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
+ obstack_object_size (&util_obstack),
+ OBJC_ENCODE_INLINE_DEFS);
+
+ /* Stack size. */
+ for (parms = DECL_ARGUMENTS (func_decl); parms;
+ parms = TREE_CHAIN (parms))
+ {
+ int parm_end = (forwarding_offset (parms)
+ + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
+ / BITS_PER_UNIT));
+
+ if (!offset_is_register && parm_end > max_parm_end)
+ max_parm_end = parm_end;
+ }
+
+ stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
+
+ sprintf (buffer, "%d", stack_size);
+ obstack_grow (&util_obstack, buffer, strlen (buffer));
+
+ /* Argument types. */
+ for (parms = DECL_ARGUMENTS (func_decl); parms;
+ parms = TREE_CHAIN (parms))
+ {
+ /* Type. */
+ encode_type (TREE_TYPE (parms),
+ obstack_object_size (&util_obstack),
+ OBJC_ENCODE_INLINE_DEFS);
+
+ /* Compute offset. */
+ sprintf (buffer, "%d", forwarding_offset (parms));
+
+ /* Indicate register. */
+ if (offset_is_register)
+ obstack_1grow (&util_obstack, '+');
+
+ obstack_grow (&util_obstack, buffer, strlen (buffer));
+ }
+
+ obstack_1grow (&util_obstack, 0);
+ result = get_identifier (obstack_finish (&util_obstack));
+ obstack_free (&util_obstack, util_firstobj);
+ return result;
+}
+
+void
+finish_method_def ()
+{
+ METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
+
+ finish_function (0);
+
+ /* Required to implement _msgSuper. This must be done AFTER finish_function,
+ since the optimizer may find "may be used before set" errors. */
+ method_context = NULL_TREE;
+}
+
+int
+lang_report_error_function (decl)
+ tree decl;
+{
+ if (method_context)
+ {
+ fprintf (stderr, "In method `%s'\n",
+ IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
+ return 1;
+ }
+
+ else
+ return 0;
+}
+
+static int
+is_complex_decl (type)
+ tree type;
+{
+ return (TREE_CODE (type) == ARRAY_TYPE
+ || TREE_CODE (type) == FUNCTION_TYPE
+ || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
+}
+
+
+/* Code to convert a decl node into text for a declaration in C. */
+
+static char tmpbuf[256];
+
+static void
+adorn_decl (decl, str)
+ tree decl;
+ char *str;
+{
+ enum tree_code code = TREE_CODE (decl);
+
+ if (code == ARRAY_REF)
+ {
+ tree an_int_cst = TREE_OPERAND (decl, 1);
+
+ if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
+ sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (an_int_cst));
+ else
+ strcat (str, "[]");
+ }
+
+ else if (code == ARRAY_TYPE)
+ {
+ tree an_int_cst = TYPE_SIZE (decl);
+ tree array_of = TREE_TYPE (decl);
+
+ if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
+ sprintf (str + strlen (str), "[%d]",
+ (TREE_INT_CST_LOW (an_int_cst)
+ / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
+ else
+ strcat (str, "[]");
+ }
+
+ else if (code == CALL_EXPR)
+ {
+ tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
+
+ strcat (str, "(");
+ while (chain)
+ {
+ gen_declaration (chain, str);
+ chain = TREE_CHAIN (chain);
+ if (chain)
+ strcat (str, ", ");
+ }
+ strcat (str, ")");
+ }
+
+ else if (code == FUNCTION_TYPE)
+ {
+ tree chain = TYPE_ARG_TYPES (decl);
+
+ strcat (str, "(");
+ while (chain && TREE_VALUE (chain) != void_type_node)
+ {
+ gen_declaration (TREE_VALUE (chain), str);
+ chain = TREE_CHAIN (chain);
+ if (chain && TREE_VALUE (chain) != void_type_node)
+ strcat (str, ", ");
+ }
+ strcat (str, ")");
+ }
+
+ else if (code == INDIRECT_REF)
+ {
+ strcpy (tmpbuf, "*");
+ if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
+ {
+ tree chain;
+
+ for (chain = nreverse (copy_list (TREE_TYPE (decl)));
+ chain;
+ chain = TREE_CHAIN (chain))
+ {
+ if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
+ {
+ strcat (tmpbuf, " ");
+ strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
+ }
+ }
+ if (str[0])
+ strcat (tmpbuf, " ");
+ }
+ strcat (tmpbuf, str);
+ strcpy (str, tmpbuf);
+ }
+
+ else if (code == POINTER_TYPE)
+ {
+ strcpy (tmpbuf, "*");
+ if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
+ {
+ if (TREE_READONLY (decl))
+ strcat (tmpbuf, " const");
+ if (TYPE_VOLATILE (decl))
+ strcat (tmpbuf, " volatile");
+ if (str[0])
+ strcat (tmpbuf, " ");
+ }
+ strcat (tmpbuf, str);
+ strcpy (str, tmpbuf);
+ }
+}
+
+static char *
+gen_declarator (decl, buf, name)
+ tree decl;
+ char *buf;
+ char *name;
+{
+ if (decl)
+ {
+ enum tree_code code = TREE_CODE (decl);
+ char *str;
+ tree op;
+ int wrap = 0;
+
+ switch (code)
+ {
+ case ARRAY_REF:
+ case INDIRECT_REF:
+ case CALL_EXPR:
+ op = TREE_OPERAND (decl, 0);
+
+ /* We have a pointer to a function or array...(*)(), (*)[] */
+ if ((code == ARRAY_REF || code == CALL_EXPR)
+ && op && TREE_CODE (op) == INDIRECT_REF)
+ wrap = 1;
+
+ str = gen_declarator (op, buf, name);
+
+ if (wrap)
+ {
+ strcpy (tmpbuf, "(");
+ strcat (tmpbuf, str);
+ strcat (tmpbuf, ")");
+ strcpy (str, tmpbuf);
+ }
+
+ adorn_decl (decl, str);
+ break;
+
+ case ARRAY_TYPE:
+ case FUNCTION_TYPE:
+ case POINTER_TYPE:
+ strcpy (buf, name);
+ str = buf;
+
+ /* This clause is done iteratively rather than recursively. */
+ do
+ {
+ op = (is_complex_decl (TREE_TYPE (decl))
+ ? TREE_TYPE (decl) : NULL_TREE);
+
+ adorn_decl (decl, str);
+
+ /* We have a pointer to a function or array...(*)(), (*)[] */
+ if (code == POINTER_TYPE
+ && op && (TREE_CODE (op) == FUNCTION_TYPE
+ || TREE_CODE (op) == ARRAY_TYPE))
+ {
+ strcpy (tmpbuf, "(");
+ strcat (tmpbuf, str);
+ strcat (tmpbuf, ")");
+ strcpy (str, tmpbuf);
+ }
+
+ decl = (is_complex_decl (TREE_TYPE (decl))
+ ? TREE_TYPE (decl) : NULL_TREE);
+ }
+
+ while (decl && (code = TREE_CODE (decl)))
+ ;
+
+ break;
+
+ case IDENTIFIER_NODE:
+ /* Will only happen if we are processing a "raw" expr-decl. */
+ strcpy (buf, IDENTIFIER_POINTER (decl));
+ return buf;
+ }
+
+ return str;
+ }
+
+ else
+ /* We have an abstract declarator or a _DECL node. */
+ {
+ strcpy (buf, name);
+ return buf;
+ }
+}
+
+static void
+gen_declspecs (declspecs, buf, raw)
+ tree declspecs;
+ char *buf;
+ int raw;
+{
+ if (raw)
+ {
+ tree chain;
+
+ for (chain = nreverse (copy_list (declspecs));
+ chain; chain = TREE_CHAIN (chain))
+ {
+ tree aspec = TREE_VALUE (chain);
+
+ if (TREE_CODE (aspec) == IDENTIFIER_NODE)
+ strcat (buf, IDENTIFIER_POINTER (aspec));
+ else if (TREE_CODE (aspec) == RECORD_TYPE)
+ {
+ if (TYPE_NAME (aspec))
+ {
+ tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
+
+ if (! TREE_STATIC_TEMPLATE (aspec))
+ strcat (buf, "struct ");
+ strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
+
+ /* NEW!!! */
+ if (protocol_list)
+ {
+ tree chain = protocol_list;
+
+ strcat (buf, " <");
+ while (chain)
+ {
+ strcat (buf,
+ IDENTIFIER_POINTER
+ (PROTOCOL_NAME (TREE_VALUE (chain))));
+ chain = TREE_CHAIN (chain);
+ if (chain)
+ strcat (buf, ", ");
+ }
+ strcat (buf, ">");
+ }
+ }
+
+ else
+ strcat (buf, "untagged struct");
+ }
+
+ else if (TREE_CODE (aspec) == UNION_TYPE)
+ {
+ if (TYPE_NAME (aspec))
+ {
+ if (! TREE_STATIC_TEMPLATE (aspec))
+ strcat (buf, "union ");
+ strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
+ }
+ else
+ strcat (buf, "untagged union");
+ }
+
+ else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
+ {
+ if (TYPE_NAME (aspec))
+ {
+ if (! TREE_STATIC_TEMPLATE (aspec))
+ strcat (buf, "enum ");
+ strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
+ }
+ else
+ strcat (buf, "untagged enum");
+ }
+
+ else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
+ strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
+
+ else if (IS_ID (aspec))
+ {
+ tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
+
+ strcat (buf, "id");
+ if (protocol_list)
+ {
+ tree chain = protocol_list;
+
+ strcat (buf, " <");
+ while (chain)
+ {
+ strcat (buf,
+ IDENTIFIER_POINTER
+ (PROTOCOL_NAME (TREE_VALUE (chain))));
+ chain = TREE_CHAIN (chain);
+ if (chain)
+ strcat (buf, ", ");
+ }
+ strcat (buf, ">");
+ }
+ }
+ if (TREE_CHAIN (chain))
+ strcat (buf, " ");
+ }
+ }
+ else
+ {
+ /* Type qualifiers. */
+ if (TREE_READONLY (declspecs))
+ strcat (buf, "const ");
+ if (TYPE_VOLATILE (declspecs))
+ strcat (buf, "volatile ");
+
+ switch (TREE_CODE (declspecs))
+ {
+ /* Type specifiers. */
+
+ case INTEGER_TYPE:
+ declspecs = TYPE_MAIN_VARIANT (declspecs);
+
+ /* Signed integer types. */
+
+ if (declspecs == short_integer_type_node)
+ strcat (buf, "short int ");
+ else if (declspecs == integer_type_node)
+ strcat (buf, "int ");
+ else if (declspecs == long_integer_type_node)
+ strcat (buf, "long int ");
+ else if (declspecs == long_long_integer_type_node)
+ strcat (buf, "long long int ");
+ else if (declspecs == signed_char_type_node
+ || declspecs == char_type_node)
+ strcat (buf, "char ");
+
+ /* Unsigned integer types. */
+
+ else if (declspecs == short_unsigned_type_node)
+ strcat (buf, "unsigned short ");
+ else if (declspecs == unsigned_type_node)
+ strcat (buf, "unsigned int ");
+ else if (declspecs == long_unsigned_type_node)
+ strcat (buf, "unsigned long ");
+ else if (declspecs == long_long_unsigned_type_node)
+ strcat (buf, "unsigned long long ");
+ else if (declspecs == unsigned_char_type_node)
+ strcat (buf, "unsigned char ");
+ break;
+
+ case REAL_TYPE:
+ declspecs = TYPE_MAIN_VARIANT (declspecs);
+
+ if (declspecs == float_type_node)
+ strcat (buf, "float ");
+ else if (declspecs == double_type_node)
+ strcat (buf, "double ");
+ else if (declspecs == long_double_type_node)
+ strcat (buf, "long double ");
+ break;
+
+ case RECORD_TYPE:
+ if (TYPE_NAME (declspecs)
+ && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
+ {
+ tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
+
+ if (! TREE_STATIC_TEMPLATE (declspecs))
+ strcat (buf, "struct ");
+ strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
+
+ if (protocol_list)
+ {
+ tree chain = protocol_list;
+
+ strcat (buf, " <");
+ while (chain)
+ {
+ strcat (buf,
+ IDENTIFIER_POINTER
+ (PROTOCOL_NAME (TREE_VALUE (chain))));
+ chain = TREE_CHAIN (chain);
+ if (chain)
+ strcat (buf, ", ");
+ }
+ strcat (buf, ">");
+ }
+ }
+
+ else
+ strcat (buf, "untagged struct");
+
+ strcat (buf, " ");
+ break;
+
+ case UNION_TYPE:
+ if (TYPE_NAME (declspecs)
+ && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
+ {
+ strcat (buf, "union ");
+ strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
+ strcat (buf, " ");
+ }
+
+ else
+ strcat (buf, "untagged union ");
+ break;
+
+ case ENUMERAL_TYPE:
+ if (TYPE_NAME (declspecs)
+ && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
+ {
+ strcat (buf, "enum ");
+ strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
+ strcat (buf, " ");
+ }
+
+ else
+ strcat (buf, "untagged enum ");
+ break;
+
+ case VOID_TYPE:
+ strcat (buf, "void ");
+ break;
+
+ case POINTER_TYPE:
+ {
+ tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
+
+ strcat (buf, "id");
+ if (protocol_list)
+ {
+ tree chain = protocol_list;
+
+ strcat (buf, " <");
+ while (chain)
+ {
+ strcat (buf,
+ IDENTIFIER_POINTER
+ (PROTOCOL_NAME (TREE_VALUE (chain))));
+ chain = TREE_CHAIN (chain);
+ if (chain)
+ strcat (buf, ", ");
+ }
+
+ strcat (buf, ">");
+ }
+ }
+ }
+ }
+}
+
+static char *
+gen_declaration (atype_or_adecl, buf)
+ tree atype_or_adecl;
+ char *buf;
+{
+ char declbuf[256];
+
+ if (TREE_CODE (atype_or_adecl) == TREE_LIST)
+ {
+ tree declspecs; /* "identifier_node", "record_type" */
+ tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
+
+ /* We have a "raw", abstract declarator (typename). */
+ declarator = TREE_VALUE (atype_or_adecl);
+ declspecs = TREE_PURPOSE (atype_or_adecl);
+
+ gen_declspecs (declspecs, buf, 1);
+ if (declarator)
+ {
+ strcat (buf, " ");
+ strcat (buf, gen_declarator (declarator, declbuf, ""));
+ }
+ }
+
+ else
+ {
+ tree atype;
+ tree declspecs; /* "integer_type", "real_type", "record_type"... */
+ tree declarator; /* "array_type", "function_type", "pointer_type". */
+
+ if (TREE_CODE (atype_or_adecl) == FIELD_DECL
+ || TREE_CODE (atype_or_adecl) == PARM_DECL
+ || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
+ atype = TREE_TYPE (atype_or_adecl);
+ else
+ /* Assume we have a *_type node. */
+ atype = atype_or_adecl;
+
+ if (is_complex_decl (atype))
+ {
+ tree chain;
+
+ /* Get the declaration specifier; it is at the end of the list. */
+ declarator = chain = atype;
+ do
+ chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
+ while (is_complex_decl (chain));
+ declspecs = chain;
+ }
+
+ else
+ {
+ declspecs = atype;
+ declarator = NULL_TREE;
+ }
+
+ gen_declspecs (declspecs, buf, 0);
+
+ if (TREE_CODE (atype_or_adecl) == FIELD_DECL
+ || TREE_CODE (atype_or_adecl) == PARM_DECL
+ || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
+ {
+ char *decl_name = (DECL_NAME (atype_or_adecl)
+ ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl))
+ : "");
+
+ if (declarator)
+ {
+ strcat (buf, " ");
+ strcat (buf, gen_declarator (declarator, declbuf, decl_name));
+ }
+
+ else if (decl_name[0])
+ {
+ strcat (buf, " ");
+ strcat (buf, decl_name);
+ }
+ }
+ else if (declarator)
+ {
+ strcat (buf, " ");
+ strcat (buf, gen_declarator (declarator, declbuf, ""));
+ }
+ }
+
+ return buf;
+}
+
+#define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
+
+static char *
+gen_method_decl (method, buf)
+ tree method;
+ char *buf;
+{
+ tree chain;
+
+ if (RAW_TYPESPEC (method) != objc_object_reference)
+ {
+ strcpy (buf, "(");
+ gen_declaration (TREE_TYPE (method), buf);
+ strcat (buf, ")");
+ }
+
+ chain = METHOD_SEL_ARGS (method);
+ if (chain)
+ {
+ /* We have a chain of keyword_decls. */
+ do
+ {
+ if (KEYWORD_KEY_NAME (chain))
+ strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
+
+ strcat (buf, ":");
+ if (RAW_TYPESPEC (chain) != objc_object_reference)
+ {
+ strcat (buf, "(");
+ gen_declaration (TREE_TYPE (chain), buf);
+ strcat (buf, ")");
+ }
+
+ strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
+ if ((chain = TREE_CHAIN (chain)))
+ strcat (buf, " ");
+ }
+ while (chain);
+
+ if (METHOD_ADD_ARGS (method) == (tree)1)
+ strcat (buf, ", ...");
+ else if (METHOD_ADD_ARGS (method))
+ {
+ /* We have a tree list node as generate by get_parm_info. */
+ chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
+
+ /* Know we have a chain of parm_decls. */
+ while (chain)
+ {
+ strcat (buf, ", ");
+ gen_declaration (chain, buf);
+ chain = TREE_CHAIN (chain);
+ }
+ }
+ }
+
+ else
+ /* We have a unary selector. */
+ strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
+
+ return buf;
+}
+
+/* Debug info. */
+
+static void
+dump_interface (fp, chain)
+ FILE *fp;
+ tree chain;
+{
+ char *buf = (char *)xmalloc (256);
+ char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
+ tree ivar_decls = CLASS_RAW_IVARS (chain);
+ tree nst_methods = CLASS_NST_METHODS (chain);
+ tree cls_methods = CLASS_CLS_METHODS (chain);
+
+ fprintf (fp, "\n@interface %s", my_name);
+
+ if (CLASS_SUPER_NAME (chain))
+ {
+ char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
+ fprintf (fp, " : %s\n", super_name);
+ }
+ else
+ fprintf (fp, "\n");
+
+ if (ivar_decls)
+ {
+ fprintf (fp, "{\n");
+ do
+ {
+ bzero (buf, 256);
+ fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
+ ivar_decls = TREE_CHAIN (ivar_decls);
+ }
+ while (ivar_decls);
+ fprintf (fp, "}\n");
+ }
+
+ while (nst_methods)
+ {
+ bzero (buf, 256);
+ fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
+ nst_methods = TREE_CHAIN (nst_methods);
+ }
+
+ while (cls_methods)
+ {
+ bzero (buf, 256);
+ fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
+ cls_methods = TREE_CHAIN (cls_methods);
+ }
+ fprintf (fp, "\n@end");
+}
+
+/* Demangle function for Objective-C */
+static const char *
+objc_demangle (mangled)
+ const char *mangled;
+{
+ char *demangled, *cp;
+
+ if (mangled[0] == '_' &&
+ (mangled[1] == 'i' || mangled[1] == 'c') &&
+ mangled[2] == '_')
+ {
+ cp = demangled = xmalloc(strlen(mangled) + 2);
+ if (mangled[1] == 'i')
+ *cp++ = '-'; /* for instance method */
+ else
+ *cp++ = '+'; /* for class method */
+ *cp++ = '['; /* opening left brace */
+ strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
+ while (*cp && *cp == '_')
+ cp++; /* skip any initial underbars in class name */
+ cp = strchr(cp, '_'); /* find first non-initial underbar */
+ if (cp == NULL)
+ {
+ free(demangled); /* not mangled name */
+ return mangled;
+ }
+ if (cp[1] == '_') /* easy case: no category name */
+ {
+ *cp++ = ' '; /* replace two '_' with one ' ' */
+ strcpy(cp, mangled + (cp - demangled) + 2);
+ }
+ else
+ {
+ *cp++ = '('; /* less easy case: category name */
+ cp = strchr(cp, '_');
+ if (cp == 0)
+ {
+ free(demangled); /* not mangled name */
+ return mangled;
+ }
+ *cp++ = ')';
+ *cp++ = ' '; /* overwriting 1st char of method name... */
+ strcpy(cp, mangled + (cp - demangled)); /* get it back */
+ }
+ while (*cp && *cp == '_')
+ cp++; /* skip any initial underbars in method name */
+ for (; *cp; cp++)
+ if (*cp == '_')
+ *cp = ':'; /* replace remaining '_' with ':' */
+ *cp++ = ']'; /* closing right brace */
+ *cp++ = 0; /* string terminator */
+ return demangled;
+ }
+ else
+ return mangled; /* not an objc mangled name */
+}
+
+static const char *
+objc_printable_name (decl, kind)
+ tree decl;
+ char **kind;
+{
+ return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
+}
+
+static void
+init_objc ()
+{
+ /* Add the special tree codes of Objective C to the tables. */
+
+#define LAST_CODE LAST_AND_UNUSED_TREE_CODE
+
+ gcc_obstack_init (&util_obstack);
+ util_firstobj = (char *) obstack_finish (&util_obstack);
+
+ tree_code_type
+ = (char **) xrealloc (tree_code_type,
+ sizeof (char *) * LAST_OBJC_TREE_CODE);
+ tree_code_length
+ = (int *) xrealloc (tree_code_length,
+ sizeof (int) * LAST_OBJC_TREE_CODE);
+ tree_code_name
+ = (char **) xrealloc (tree_code_name,
+ sizeof (char *) * LAST_OBJC_TREE_CODE);
+ bcopy ((char *) objc_tree_code_type,
+ (char *) (tree_code_type + (int) LAST_CODE),
+ (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
+ * sizeof (char *)));
+ bcopy ((char *) objc_tree_code_length,
+ (char *) (tree_code_length + (int) LAST_CODE),
+ (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
+ * sizeof (int)));
+ bcopy ((char *) objc_tree_code_name,
+ (char *) (tree_code_name + (int) LAST_CODE),
+ (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE)
+ * sizeof (char *)));
+
+ errbuf = (char *)xmalloc (BUFSIZE);
+ hash_init ();
+ synth_module_prologue ();
+
+ /* Change the default error function */
+ decl_printable_name = (char* (*)()) objc_printable_name;
+}
+
+static void
+finish_objc ()
+{
+ struct imp_entry *impent;
+ tree chain;
+ /* The internally generated initializers appear to have missing braces.
+ Don't warn about this. */
+ int save_warn_missing_braces = warn_missing_braces;
+ warn_missing_braces = 0;
+
+ generate_forward_declaration_to_string_table ();
+
+#ifdef OBJC_PROLOGUE
+ OBJC_PROLOGUE;
+#endif
+
+ /* Process the static instances here because initialization of objc_symtab
+ depends on them. */
+ if (objc_static_instances)
+ generate_static_references ();
+
+ if (implementation_context || class_names_chain
+ || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
+ generate_objc_symtab_decl ();
+
+ for (impent = imp_list; impent; impent = impent->next)
+ {
+ implementation_context = impent->imp_context;
+ implementation_template = impent->imp_template;
+
+ UOBJC_CLASS_decl = impent->class_decl;
+ UOBJC_METACLASS_decl = impent->meta_decl;
+
+ if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
+ {
+ /* all of the following reference the string pool... */
+ generate_ivar_lists ();
+ generate_dispatch_tables ();
+ generate_shared_structures ();
+ }
+ else
+ {
+ generate_dispatch_tables ();
+ generate_category (implementation_context);
+ }
+ }
+
+ /* If we are using an array of selectors, we must always
+ finish up the array decl even if no selectors were used. */
+ if (! flag_next_runtime || sel_ref_chain)
+ build_selector_translation_table ();
+
+ if (protocol_chain)
+ generate_protocols ();
+
+ if (implementation_context || class_names_chain || objc_static_instances
+ || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
+ {
+ /* Arrange for Objc data structures to be initialized at run time. */
+ char *init_name = build_module_descriptor ();
+ if (init_name)
+ assemble_constructor (init_name);
+ }
+
+ /* Dump the class references. This forces the appropriate classes
+ to be linked into the executable image, preserving unix archive
+ semantics. This can be removed when we move to a more dynamically
+ linked environment. */
+
+ for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
+ {
+ handle_class_ref (chain);
+ if (TREE_PURPOSE (chain))
+ generate_classref_translation_entry (chain);
+ }
+
+ for (impent = imp_list; impent; impent = impent->next)
+ handle_impent (impent);
+
+ /* Dump the string table last. */
+
+ generate_strings ();
+
+ if (flag_gen_declaration)
+ {
+ add_class (implementation_context);
+ dump_interface (gen_declaration_file, implementation_context);
+ }
+
+ if (warn_selector)
+ {
+ int slot;
+ hash hsh;
+
+ /* Run through the selector hash tables and print a warning for any
+ selector which has multiple methods. */
+
+ for (slot = 0; slot < SIZEHASHTABLE; slot++)
+ for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
+ if (hsh->list)
+ {
+ tree meth = hsh->key;
+ char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
+ ? '-' : '+');
+ attr loop;
+
+ warning ("potential selector conflict for method `%s'",
+ IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
+ warn_with_method ("found", type, meth);
+ for (loop = hsh->list; loop; loop = loop->next)
+ warn_with_method ("found", type, loop->value);
+ }
+
+ for (slot = 0; slot < SIZEHASHTABLE; slot++)
+ for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
+ if (hsh->list)
+ {
+ tree meth = hsh->key;
+ char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
+ ? '-' : '+');
+ attr loop;
+
+ warning ("potential selector conflict for method `%s'",
+ IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
+ warn_with_method ("found", type, meth);
+ for (loop = hsh->list; loop; loop = loop->next)
+ warn_with_method ("found", type, loop->value);
+ }
+ }
+
+ warn_missing_braces = save_warn_missing_braces;
+}
+
+/* Subroutines of finish_objc. */
+
+static void
+generate_classref_translation_entry (chain)
+ tree chain;
+{
+ tree expr, name, decl_specs, decl, sc_spec;
+ tree type;
+
+ type = TREE_TYPE (TREE_PURPOSE (chain));
+
+ expr = add_objc_string (TREE_VALUE (chain), class_names);
+ expr = build_c_cast (type, expr); /* cast! */
+
+ name = DECL_NAME (TREE_PURPOSE (chain));
+
+ sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
+
+ /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
+ decl_specs = tree_cons (NULL_TREE, type, sc_spec);
+
+ /* The decl that is returned from start_decl is the one that we
+ forward declared in build_class_reference. */
+ decl = start_decl (name, decl_specs, 1, NULL_TREE, NULL_TREE);
+ finish_decl (decl, expr, NULL_TREE);
+ return;
+}
+
+static void
+handle_class_ref (chain)
+ tree chain;
+{
+ char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
+ if (! flag_next_runtime)
+ {
+ tree decl;
+ char *string = (char *) alloca (strlen (name) + 30);
+ tree exp;
+
+ sprintf (string, "%sobjc_class_name_%s",
+ (flag_next_runtime ? "." : "__"), name);
+
+ /* Make a decl for this name, so we can use its address in a tree. */
+ decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+
+ pushdecl (decl);
+ rest_of_decl_compilation (decl, 0, 0, 0);
+
+ /* Make following constant read-only (why not)? */
+ readonly_data_section ();
+
+ exp = build1 (ADDR_EXPR, string_type_node, decl);
+
+ /* Align the section properly. */
+ assemble_constant_align (exp);
+
+ /* Inform the assembler about this new external thing. */
+ assemble_external (decl);
+
+ /* Output a constant to reference this address. */
+ output_constant (exp, int_size_in_bytes (string_type_node));
+ }
+ else
+ {
+ /* This overreliance on our assembler (i.e. lack of portability)
+ should be dealt with at some point. The GNU strategy (above)
+ won't work either, but it is a start. */
+ char *string = (char *) alloca (strlen (name) + 30);
+ sprintf (string, ".reference .objc_class_name_%s", name);
+ assemble_asm (my_build_string (strlen (string) + 1, string));
+ }
+}
+
+static void
+handle_impent (impent)
+ struct imp_entry *impent;
+{
+ implementation_context = impent->imp_context;
+ implementation_template = impent->imp_template;
+
+ if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
+ {
+ char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
+ char *string = (char *) alloca (strlen (class_name) + 30);
+
+ if (flag_next_runtime)
+ {
+ /* Grossly unportable.
+ People should know better than to assume
+ such things about assembler syntax! */
+ sprintf (string, ".objc_class_name_%s=0", class_name);
+ assemble_asm (my_build_string (strlen (string) + 1, string));
+
+ sprintf (string, ".globl .objc_class_name_%s", class_name);
+ assemble_asm (my_build_string (strlen (string) + 1, string));
+ }
+
+ else
+ {
+ sprintf (string, "%sobjc_class_name_%s",
+ (flag_next_runtime ? "." : "__"), class_name);
+ assemble_global (string);
+ assemble_label (string);
+ }
+ }
+
+ else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
+ {
+ char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
+ char *class_super_name
+ = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
+ char *string = (char *) alloca (strlen (class_name)
+ + strlen (class_super_name) + 30);
+
+ /* Do the same for categories. Even though no references to these
+ symbols are generated automatically by the compiler, it gives
+ you a handle to pull them into an archive by hand. */
+ if (flag_next_runtime)
+ {
+ /* Grossly unportable. */
+ sprintf (string, ".objc_category_name_%s_%s=0",
+ class_name, class_super_name);
+ assemble_asm (my_build_string (strlen (string) + 1, string));
+
+ sprintf (string, ".globl .objc_category_name_%s_%s",
+ class_name, class_super_name);
+ assemble_asm (my_build_string (strlen (string) + 1, string));
+ }
+
+ else
+ {
+ sprintf (string, "%sobjc_category_name_%s_%s",
+ (flag_next_runtime ? "." : "__"),
+ class_name, class_super_name);
+ assemble_global (string);
+ assemble_label (string);
+ }
+ }
+}
+
+#ifdef DEBUG
+
+static void
+objc_debug (fp)
+ FILE *fp;
+{
+ char *buf = (char *)xmalloc (256);
+
+ { /* dump function prototypes */
+ tree loop = UOBJC_MODULES_decl;
+
+ fprintf (fp, "\n\nfunction prototypes:\n");
+ while (loop)
+ {
+ if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
+ {
+ /* We have a function definition: generate prototype. */
+ bzero (errbuf, BUFSIZE);
+ gen_declaration (loop, errbuf);
+ fprintf (fp, "%s;\n", errbuf);
+ }
+ loop = TREE_CHAIN (loop);
+ }
+ }
+ {
+ /* Dump global chains. */
+ tree loop;
+ int i, index = 0, offset = 0;
+ hash hashlist;
+
+ for (i = 0; i < SIZEHASHTABLE; i++)
+ {
+ if (hashlist = nst_method_hash_list[i])
+ {
+ fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
+ do
+ {
+ bzero (buf, 256);
+ fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
+ hashlist = hashlist->next;
+ }
+ while (hashlist);
+ }
+ }
+
+ for (i = 0; i < SIZEHASHTABLE; i++)
+ {
+ if (hashlist = cls_method_hash_list[i])
+ {
+ fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
+ do
+ {
+ bzero (buf, 256);
+ fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
+ hashlist = hashlist->next;
+ }
+ while (hashlist);
+ }
+ }
+
+ fprintf (fp, "\nsel_refdef_chain:\n");
+ for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
+ {
+ fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
+ IDENTIFIER_POINTER (TREE_VALUE (loop)));
+ index++;
+ /* add one for the '\0' character */
+ offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
+ }
+
+ fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
+ }
+}
+#endif
+
+void
+print_lang_statistics ()
+{
+}
diff --git a/gnu/usr.bin/gcc/objc/objc-act.h b/gnu/usr.bin/gcc/objc/objc-act.h
new file mode 100644
index 00000000000..65224de84f4
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/objc-act.h
@@ -0,0 +1,117 @@
+/* Declarations for objc-act.c.
+ Copyright (C) 1990 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. */
+
+
+/*** Public Interface (procedures) ***/
+
+/* used by yyparse */
+
+void finish_file PROTO((void));
+tree start_class PROTO((enum tree_code, tree, tree, tree));
+tree continue_class PROTO((tree));
+void finish_class PROTO((tree));
+void start_method_def PROTO((tree));
+void continue_method_def PROTO((void));
+void finish_method_def PROTO((void));
+tree start_protocol PROTO((enum tree_code, tree, tree));
+void finish_protocol PROTO((tree));
+void add_objc_decls PROTO((void));
+
+tree is_ivar PROTO((tree, tree));
+int is_private PROTO((tree));
+int is_public PROTO((tree, tree));
+tree add_instance_variable PROTO((tree, int, tree, tree, tree));
+tree add_class_method PROTO((tree, tree));
+tree add_instance_method PROTO((tree, tree));
+tree get_super_receiver PROTO((void));
+tree get_class_ivars PROTO((tree));
+tree get_class_reference PROTO((tree));
+tree get_static_reference PROTO((tree, tree));
+tree get_object_reference PROTO((tree));
+tree build_message_expr PROTO((tree));
+tree build_selector_expr PROTO((tree));
+tree build_ivar_reference PROTO((tree));
+tree build_keyword_decl PROTO((tree, tree, tree));
+tree build_method_decl PROTO((enum tree_code, tree, tree, tree));
+tree build_protocol_expr PROTO((tree));
+tree build_objc_string_object PROTO((tree));
+
+extern tree objc_ivar_chain;
+extern tree objc_method_context;
+
+void objc_declare_alias PROTO((tree, tree));
+void objc_declare_class PROTO((tree));
+
+extern int objc_receiver_context;
+
+/* the following routines are used to implement statically typed objects */
+
+int objc_comptypes PROTO((tree, tree, int));
+void objc_check_decl PROTO((tree));
+
+/* NeXT extensions */
+
+tree build_encode_expr PROTO((tree));
+
+/* Objective-C structures */
+
+/* KEYWORD_DECL */
+#define KEYWORD_KEY_NAME(DECL) ((DECL)->decl.name)
+#define KEYWORD_ARG_NAME(DECL) ((DECL)->decl.arguments)
+
+/* INSTANCE_METHOD_DECL, CLASS_METHOD_DECL */
+#define METHOD_SEL_NAME(DECL) ((DECL)->decl.name)
+#define METHOD_SEL_ARGS(DECL) ((DECL)->decl.arguments)
+#define METHOD_ADD_ARGS(DECL) ((DECL)->decl.result)
+#define METHOD_DEFINITION(DECL) ((DECL)->decl.initial)
+#define METHOD_ENCODING(DECL) ((DECL)->decl.context)
+
+/* CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
+ CATEGORY_INTERFACE_TYPE, CATEGORY_IMPLEMENTATION_TYPE,
+ PROTOCOL_INTERFACE_TYPE */
+#define CLASS_NAME(CLASS) ((CLASS)->type.name)
+#define CLASS_SUPER_NAME(CLASS) ((CLASS)->type.context)
+#define CLASS_IVARS(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 0)
+#define CLASS_RAW_IVARS(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1)
+#define CLASS_NST_METHODS(CLASS) ((CLASS)->type.minval)
+#define CLASS_CLS_METHODS(CLASS) ((CLASS)->type.maxval)
+#define CLASS_STATIC_TEMPLATE(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 2)
+#define CLASS_CATEGORY_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 3)
+#define CLASS_PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 4)
+#define PROTOCOL_NAME(CLASS) ((CLASS)->type.name)
+#define PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 0)
+#define PROTOCOL_NST_METHODS(CLASS) ((CLASS)->type.minval)
+#define PROTOCOL_CLS_METHODS(CLASS) ((CLASS)->type.maxval)
+#define PROTOCOL_FORWARD_DECL(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1)
+#define TYPE_PROTOCOL_LIST(TYPE) ((TYPE)->type.context)
+
+/* Define the Objective-C or Objective-C++ language-specific tree codes. */
+
+#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,
+enum objc_tree_code {
+#ifdef OBJCPLUS
+ dummy_tree_code = LAST_CPLUS_TREE_CODE,
+#else
+ dummy_tree_code = LAST_AND_UNUSED_TREE_CODE,
+#endif
+#include "objc-tree.def"
+ LAST_OBJC_TREE_CODE
+};
+#undef DEFTREECODE
diff --git a/gnu/usr.bin/gcc/objc/objc-list.h b/gnu/usr.bin/gcc/objc/objc-list.h
new file mode 100644
index 00000000000..19760906238
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/objc-list.h
@@ -0,0 +1,147 @@
+/* Generic single linked list to keep various information
+ Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+ Contributed by Kresten Krab Thorup.
+
+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. */
+
+/* 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. */
+
+#ifndef __GNU_OBJC_LIST_H
+#define __GNU_OBJC_LIST_H
+
+struct objc_list {
+ void *head;
+ struct objc_list *tail;
+};
+
+/* Return a cons cell produced from (head . tail) */
+
+static inline struct objc_list*
+list_cons(void* head, struct objc_list* tail)
+{
+ struct objc_list* cell;
+
+ cell = (struct objc_list*)objc_malloc(sizeof(struct objc_list));
+ cell->head = head;
+ cell->tail = tail;
+ return cell;
+}
+
+/* Return the length of a list, list_length(NULL) returns zero */
+
+static inline int
+list_length(struct objc_list* list)
+{
+ int i = 0;
+ while(list)
+ {
+ i += 1;
+ list = list->tail;
+ }
+ return i;
+}
+
+/* Return the Nth element of LIST, where N count from zero. If N
+ larger than the list length, NULL is returned */
+
+static inline void*
+list_nth(int index, struct objc_list* list)
+{
+ while(index-- != 0)
+ {
+ if(list->tail)
+ list = list->tail;
+ else
+ return 0;
+ }
+ return list->head;
+}
+
+/* Remove the element at the head by replacing it by its successor */
+
+static inline void
+list_remove_head(struct objc_list** list)
+{
+ if ((*list)->tail)
+ {
+ struct objc_list* tail = (*list)->tail; /* fetch next */
+ *(*list) = *tail; /* copy next to list head */
+ objc_free(tail); /* free next */
+ }
+ else /* only one element in list */
+ {
+ objc_free(*list);
+ (*list) = 0;
+ }
+}
+
+
+/* Remove the element with `car' set to ELEMENT */
+
+static inline void
+list_remove_elem(struct objc_list** list, void* elem)
+{
+ while (*list) {
+ if ((*list)->head == elem)
+ list_remove_head(list);
+ list = &((*list)->tail);
+ }
+}
+
+/* Map FUNCTION over all elements in LIST */
+
+static inline void
+list_mapcar(struct objc_list* list, void(*function)(void*))
+{
+ while(list)
+ {
+ (*function)(list->head);
+ list = list->tail;
+ }
+}
+
+/* Return element that has ELEM as car */
+
+static inline struct objc_list**
+list_find(struct objc_list** list, void* elem)
+{
+ while(*list)
+ {
+ if ((*list)->head == elem)
+ return list;
+ list = &((*list)->tail);
+ }
+ return NULL;
+}
+
+/* Free list (backwards recursive) */
+
+static void
+list_free(struct objc_list* list)
+{
+ if(list)
+ {
+ list_free(list->tail);
+ objc_free(list);
+ }
+}
+#endif __GNU_OBJC_LIST_H
diff --git a/gnu/usr.bin/gcc/objc/objc-parse.c b/gnu/usr.bin/gcc/objc/objc-parse.c
new file mode 100644
index 00000000000..9c80c878ad4
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/objc-parse.c
@@ -0,0 +1,5111 @@
+
+/* A Bison parser, made from objc-parse.y with Bison version GNU Bison version 1.24
+ */
+
+#define YYBISON 1 /* Identify Bison output. */
+
+#define IDENTIFIER 258
+#define TYPENAME 259
+#define SCSPEC 260
+#define TYPESPEC 261
+#define TYPE_QUAL 262
+#define CONSTANT 263
+#define STRING 264
+#define ELLIPSIS 265
+#define SIZEOF 266
+#define ENUM 267
+#define STRUCT 268
+#define UNION 269
+#define IF 270
+#define ELSE 271
+#define WHILE 272
+#define DO 273
+#define FOR 274
+#define SWITCH 275
+#define CASE 276
+#define DEFAULT 277
+#define BREAK 278
+#define CONTINUE 279
+#define RETURN 280
+#define GOTO 281
+#define ASM_KEYWORD 282
+#define TYPEOF 283
+#define ALIGNOF 284
+#define ATTRIBUTE 285
+#define EXTENSION 286
+#define LABEL 287
+#define REALPART 288
+#define IMAGPART 289
+#define ASSIGN 290
+#define OROR 291
+#define ANDAND 292
+#define EQCOMPARE 293
+#define ARITHCOMPARE 294
+#define LSHIFT 295
+#define RSHIFT 296
+#define UNARY 297
+#define PLUSPLUS 298
+#define MINUSMINUS 299
+#define HYPERUNARY 300
+#define POINTSAT 301
+#define INTERFACE 302
+#define IMPLEMENTATION 303
+#define END 304
+#define SELECTOR 305
+#define DEFS 306
+#define ENCODE 307
+#define CLASSNAME 308
+#define PUBLIC 309
+#define PRIVATE 310
+#define PROTECTED 311
+#define PROTOCOL 312
+#define OBJECTNAME 313
+#define CLASS 314
+#define ALIAS 315
+#define OBJC_STRING 316
+
+#line 33 "objc-parse.y"
+
+#include "config.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <setjmp.h>
+
+#include "tree.h"
+#include "input.h"
+#include "c-lex.h"
+#include "c-tree.h"
+#include "flags.h"
+
+#ifdef MULTIBYTE_CHARS
+#include <stdlib.h>
+#include <locale.h>
+#endif
+
+#include "objc-act.h"
+
+/* Since parsers are distinct for each language, put the language string
+ definition here. */
+char *language_string = "GNU Obj-C";
+
+#ifndef errno
+extern int errno;
+#endif
+
+void yyerror ();
+
+/* Like YYERROR but do call yyerror. */
+#define YYERROR1 { yyerror ("syntax error"); YYERROR; }
+
+/* Cause the `yydebug' variable to be defined. */
+#define YYDEBUG 1
+
+#line 72 "objc-parse.y"
+typedef union {long itype; tree ttype; enum tree_code code;
+ char *filename; int lineno; int ends_in_label; } YYSTYPE;
+#line 199 "objc-parse.y"
+
+/* Number of statements (loosely speaking) and compound statements
+ seen so far. */
+static int stmt_count;
+static int compstmt_count;
+
+/* Input file and line number of the end of the body of last simple_if;
+ used by the stmt-rule immediately after simple_if returns. */
+static char *if_stmt_file;
+static int if_stmt_line;
+
+/* List of types and structure classes of the current declaration. */
+static tree current_declspecs = NULL_TREE;
+static tree prefix_attributes = NULL_TREE;
+
+/* Stack of saved values of current_declspecs and prefix_attributes. */
+static tree declspec_stack;
+
+/* 1 if we explained undeclared var errors. */
+static int undeclared_variable_notice;
+
+/* Objective-C specific information */
+
+tree objc_interface_context;
+tree objc_implementation_context;
+tree objc_method_context;
+tree objc_ivar_chain;
+tree objc_ivar_context;
+enum tree_code objc_inherit_code;
+int objc_receiver_context;
+int objc_public_flag;
+
+
+/* Tell yyparse how to print a token's value, if yydebug is set. */
+
+#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
+extern void yyprint ();
+
+#ifndef YYLTYPE
+typedef
+ struct yyltype
+ {
+ int timestamp;
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+ char *text;
+ }
+ yyltype;
+
+#define YYLTYPE yyltype
+#endif
+
+#include <stdio.h>
+
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
+
+
+
+#define YYFINAL 941
+#define YYFLAG -32768
+#define YYNTBASE 84
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 316 ? yytranslate[x] : 306)
+
+static const char yytranslate[] = { 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 80, 2, 2, 2, 52, 43, 2, 59,
+ 76, 50, 48, 81, 49, 58, 51, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 38, 77, 2,
+ 36, 2, 37, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 60, 2, 83, 42, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 82, 41, 78, 79, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 39, 40, 44, 45, 46, 47, 53, 54, 55, 56,
+ 57, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75
+};
+
+#if YYDEBUG != 0
+static const short yyprhs[] = { 0,
+ 0, 1, 3, 4, 7, 8, 12, 14, 16, 18,
+ 24, 27, 31, 36, 41, 44, 47, 50, 53, 55,
+ 56, 57, 65, 70, 71, 72, 80, 85, 86, 87,
+ 94, 98, 100, 102, 104, 106, 108, 110, 112, 114,
+ 116, 118, 120, 122, 123, 125, 127, 131, 133, 136,
+ 139, 142, 145, 148, 153, 156, 161, 164, 167, 169,
+ 171, 173, 178, 179, 187, 189, 193, 197, 201, 205,
+ 209, 213, 217, 221, 225, 229, 233, 237, 238, 243,
+ 244, 249, 250, 251, 259, 260, 266, 270, 274, 276,
+ 278, 280, 284, 288, 289, 294, 299, 304, 308, 312,
+ 315, 318, 320, 322, 324, 326, 328, 330, 333, 335,
+ 338, 339, 341, 344, 348, 350, 352, 355, 358, 363,
+ 368, 371, 374, 378, 380, 382, 385, 388, 389, 390,
+ 395, 400, 404, 408, 411, 414, 417, 420, 424, 425,
+ 428, 431, 434, 437, 441, 442, 445, 448, 450, 452,
+ 455, 458, 460, 462, 465, 468, 471, 475, 476, 479,
+ 481, 483, 485, 488, 491, 493, 498, 503, 505, 507,
+ 509, 511, 515, 517, 521, 522, 527, 528, 535, 539,
+ 540, 547, 551, 552, 554, 556, 559, 566, 568, 572,
+ 573, 575, 580, 587, 592, 594, 596, 598, 600, 602,
+ 603, 608, 610, 611, 614, 616, 620, 622, 623, 628,
+ 630, 631, 636, 637, 643, 644, 645, 651, 652, 653,
+ 659, 661, 663, 667, 671, 676, 680, 684, 688, 690,
+ 692, 696, 701, 705, 709, 713, 715, 719, 723, 727,
+ 732, 736, 740, 742, 743, 751, 757, 760, 761, 769,
+ 775, 778, 779, 788, 789, 797, 800, 801, 803, 804,
+ 806, 808, 811, 812, 816, 819, 824, 828, 830, 834,
+ 836, 838, 841, 843, 847, 852, 859, 865, 867, 871,
+ 873, 875, 879, 882, 885, 886, 888, 890, 893, 894,
+ 897, 901, 905, 908, 912, 917, 921, 924, 928, 931,
+ 933, 935, 938, 941, 942, 944, 947, 948, 949, 951,
+ 953, 956, 960, 962, 965, 967, 970, 977, 983, 989,
+ 992, 995, 1000, 1001, 1006, 1007, 1008, 1012, 1017, 1021,
+ 1023, 1025, 1027, 1029, 1032, 1033, 1038, 1040, 1044, 1045,
+ 1046, 1054, 1060, 1063, 1064, 1065, 1066, 1079, 1080, 1087,
+ 1090, 1093, 1096, 1100, 1107, 1116, 1127, 1140, 1144, 1149,
+ 1151, 1153, 1154, 1161, 1165, 1171, 1174, 1177, 1178, 1180,
+ 1181, 1183, 1184, 1186, 1188, 1192, 1197, 1199, 1203, 1204,
+ 1207, 1210, 1211, 1216, 1219, 1220, 1222, 1224, 1228, 1230,
+ 1234, 1239, 1244, 1249, 1254, 1259, 1260, 1263, 1265, 1268,
+ 1270, 1274, 1276, 1280, 1282, 1284, 1286, 1288, 1290, 1292,
+ 1294, 1296, 1300, 1304, 1309, 1310, 1311, 1322, 1323, 1330,
+ 1331, 1332, 1345, 1346, 1355, 1356, 1363, 1366, 1367, 1376,
+ 1381, 1382, 1392, 1398, 1399, 1406, 1407, 1409, 1413, 1417,
+ 1419, 1421, 1423, 1425, 1426, 1430, 1433, 1437, 1441, 1443,
+ 1444, 1446, 1450, 1452, 1456, 1459, 1460, 1461, 1462, 1470,
+ 1471, 1472, 1473, 1481, 1482, 1483, 1486, 1488, 1490, 1493,
+ 1494, 1498, 1500, 1502, 1503, 1504, 1510, 1511, 1512, 1518,
+ 1523, 1525, 1531, 1534, 1535, 1538, 1539, 1541, 1543, 1545,
+ 1548, 1551, 1556, 1559, 1562, 1564, 1568, 1571, 1574, 1577,
+ 1578, 1581, 1582, 1586, 1588, 1590, 1593, 1595, 1597, 1599,
+ 1601, 1603, 1605, 1607, 1609, 1611, 1613, 1615, 1617, 1619,
+ 1621, 1623, 1625, 1627, 1629, 1631, 1633, 1635, 1637, 1639,
+ 1641, 1643, 1650, 1654, 1660, 1663, 1665, 1667, 1669, 1672,
+ 1674, 1678, 1681, 1683, 1685, 1686, 1687, 1694, 1696, 1698,
+ 1700, 1703, 1706, 1708, 1713, 1718
+};
+
+static const short yyrhs[] = { -1,
+ 85, 0, 0, 86, 88, 0, 0, 85, 87, 88,
+ 0, 90, 0, 89, 0, 237, 0, 27, 59, 99,
+ 76, 77, 0, 236, 88, 0, 123, 137, 77, 0,
+ 130, 123, 137, 77, 0, 126, 123, 136, 77, 0,
+ 130, 77, 0, 126, 77, 0, 1, 77, 0, 1,
+ 78, 0, 77, 0, 0, 0, 126, 123, 163, 91,
+ 117, 92, 194, 0, 126, 123, 163, 1, 0, 0,
+ 0, 130, 123, 166, 93, 117, 94, 194, 0, 130,
+ 123, 166, 1, 0, 0, 0, 123, 166, 95, 117,
+ 96, 194, 0, 123, 166, 1, 0, 3, 0, 4,
+ 0, 72, 0, 67, 0, 43, 0, 49, 0, 48,
+ 0, 54, 0, 55, 0, 79, 0, 80, 0, 101,
+ 0, 0, 101, 0, 107, 0, 101, 81, 107, 0,
+ 113, 0, 50, 105, 0, 236, 105, 0, 98, 105,
+ 0, 40, 97, 0, 103, 102, 0, 103, 59, 181,
+ 76, 0, 104, 102, 0, 104, 59, 181, 76, 0,
+ 33, 105, 0, 34, 105, 0, 11, 0, 29, 0,
+ 102, 0, 59, 181, 76, 105, 0, 0, 59, 181,
+ 76, 82, 106, 151, 78, 0, 105, 0, 107, 48,
+ 107, 0, 107, 49, 107, 0, 107, 50, 107, 0,
+ 107, 51, 107, 0, 107, 52, 107, 0, 107, 46,
+ 107, 0, 107, 47, 107, 0, 107, 45, 107, 0,
+ 107, 44, 107, 0, 107, 43, 107, 0, 107, 41,
+ 107, 0, 107, 42, 107, 0, 0, 107, 40, 108,
+ 107, 0, 0, 107, 39, 109, 107, 0, 0, 0,
+ 107, 37, 110, 99, 38, 111, 107, 0, 0, 107,
+ 37, 112, 38, 107, 0, 107, 36, 107, 0, 107,
+ 35, 107, 0, 3, 0, 8, 0, 115, 0, 59,
+ 99, 76, 0, 59, 1, 76, 0, 0, 59, 114,
+ 196, 76, 0, 113, 59, 100, 76, 0, 113, 60,
+ 99, 83, 0, 113, 58, 97, 0, 113, 57, 97,
+ 0, 113, 54, 0, 113, 55, 0, 297, 0, 303,
+ 0, 304, 0, 305, 0, 116, 0, 9, 0, 115,
+ 9, 0, 75, 0, 116, 75, 0, 0, 119, 0,
+ 119, 10, 0, 201, 202, 120, 0, 118, 0, 189,
+ 0, 119, 118, 0, 118, 189, 0, 128, 123, 136,
+ 77, 0, 131, 123, 137, 77, 0, 128, 77, 0,
+ 131, 77, 0, 201, 202, 125, 0, 121, 0, 189,
+ 0, 122, 121, 0, 121, 189, 0, 0, 0, 126,
+ 123, 136, 77, 0, 130, 123, 137, 77, 0, 126,
+ 123, 157, 0, 130, 123, 160, 0, 126, 77, 0,
+ 130, 77, 0, 236, 125, 0, 134, 127, 0, 130,
+ 134, 127, 0, 0, 127, 135, 0, 127, 5, 0,
+ 127, 144, 0, 134, 129, 0, 131, 134, 129, 0,
+ 0, 129, 135, 0, 129, 5, 0, 131, 0, 144,
+ 0, 130, 131, 0, 130, 144, 0, 7, 0, 5,
+ 0, 131, 7, 0, 131, 5, 0, 134, 133, 0,
+ 183, 134, 133, 0, 0, 133, 135, 0, 6, 0,
+ 167, 0, 4, 0, 67, 253, 0, 72, 253, 0,
+ 254, 0, 28, 59, 99, 76, 0, 28, 59, 181,
+ 76, 0, 6, 0, 7, 0, 167, 0, 139, 0,
+ 136, 81, 139, 0, 141, 0, 137, 81, 139, 0,
+ 0, 27, 59, 115, 76, 0, 0, 163, 138, 143,
+ 36, 140, 149, 0, 163, 138, 143, 0, 0, 166,
+ 138, 143, 36, 142, 149, 0, 166, 138, 143, 0,
+ 0, 144, 0, 145, 0, 144, 145, 0, 30, 59,
+ 59, 146, 76, 76, 0, 147, 0, 146, 81, 147,
+ 0, 0, 148, 0, 148, 59, 3, 76, 0, 148,
+ 59, 3, 81, 101, 76, 0, 148, 59, 100, 76,
+ 0, 97, 0, 5, 0, 6, 0, 7, 0, 107,
+ 0, 0, 82, 150, 151, 78, 0, 1, 0, 0,
+ 152, 172, 0, 153, 0, 152, 81, 153, 0, 107,
+ 0, 0, 82, 154, 151, 78, 0, 1, 0, 0,
+ 97, 38, 155, 153, 0, 0, 58, 97, 36, 156,
+ 153, 0, 0, 0, 163, 158, 117, 159, 196, 0,
+ 0, 0, 166, 161, 117, 162, 196, 0, 164, 0,
+ 166, 0, 59, 164, 76, 0, 164, 59, 231, 0,
+ 164, 60, 99, 83, 0, 164, 60, 83, 0, 50,
+ 184, 164, 0, 144, 124, 164, 0, 4, 0, 72,
+ 0, 165, 59, 231, 0, 165, 60, 99, 83, 0,
+ 165, 60, 83, 0, 50, 184, 165, 0, 144, 124,
+ 165, 0, 4, 0, 166, 59, 231, 0, 59, 166,
+ 76, 0, 50, 184, 166, 0, 166, 60, 99, 83,
+ 0, 166, 60, 83, 0, 144, 124, 166, 0, 3,
+ 0, 0, 13, 97, 82, 168, 174, 78, 143, 0,
+ 13, 82, 174, 78, 143, 0, 13, 97, 0, 0,
+ 14, 97, 82, 169, 174, 78, 143, 0, 14, 82,
+ 174, 78, 143, 0, 14, 97, 0, 0, 12, 97,
+ 82, 170, 179, 173, 78, 143, 0, 0, 12, 82,
+ 171, 179, 173, 78, 143, 0, 12, 97, 0, 0,
+ 81, 0, 0, 81, 0, 175, 0, 175, 176, 0,
+ 0, 175, 176, 77, 0, 175, 77, 0, 65, 59,
+ 67, 76, 0, 132, 123, 177, 0, 132, 0, 183,
+ 123, 177, 0, 183, 0, 1, 0, 236, 176, 0,
+ 178, 0, 177, 81, 178, 0, 201, 202, 163, 143,
+ 0, 201, 202, 163, 38, 107, 143, 0, 201, 202,
+ 38, 107, 143, 0, 180, 0, 179, 81, 180, 0,
+ 1, 0, 97, 0, 97, 36, 107, 0, 132, 182,
+ 0, 183, 182, 0, 0, 185, 0, 7, 0, 183,
+ 7, 0, 0, 184, 7, 0, 59, 185, 76, 0,
+ 50, 184, 185, 0, 50, 184, 0, 185, 59, 224,
+ 0, 185, 60, 99, 83, 0, 185, 60, 83, 0,
+ 59, 224, 0, 60, 99, 83, 0, 60, 83, 0,
+ 187, 0, 204, 0, 187, 204, 0, 187, 189, 0,
+ 0, 186, 0, 1, 77, 0, 0, 0, 192, 0,
+ 193, 0, 192, 193, 0, 32, 235, 77, 0, 196,
+ 0, 1, 196, 0, 82, 0, 195, 78, 0, 195,
+ 190, 191, 122, 188, 78, 0, 195, 190, 191, 1,
+ 78, 0, 195, 190, 191, 186, 78, 0, 198, 203,
+ 0, 198, 1, 0, 15, 59, 99, 76, 0, 0,
+ 18, 200, 203, 17, 0, 0, 0, 201, 202, 206,
+ 0, 201, 202, 217, 203, 0, 201, 202, 205, 0,
+ 206, 0, 217, 0, 196, 0, 214, 0, 99, 77,
+ 0, 0, 197, 16, 207, 203, 0, 197, 0, 197,
+ 16, 1, 0, 0, 0, 17, 208, 59, 99, 76,
+ 209, 203, 0, 199, 59, 99, 76, 77, 0, 199,
+ 1, 0, 0, 0, 0, 19, 59, 219, 77, 210,
+ 219, 77, 211, 219, 76, 212, 203, 0, 0, 20,
+ 59, 99, 76, 213, 203, 0, 23, 77, 0, 24,
+ 77, 0, 25, 77, 0, 25, 99, 77, 0, 27,
+ 218, 59, 99, 76, 77, 0, 27, 218, 59, 99,
+ 38, 220, 76, 77, 0, 27, 218, 59, 99, 38,
+ 220, 38, 220, 76, 77, 0, 27, 218, 59, 99,
+ 38, 220, 38, 220, 38, 223, 76, 77, 0, 26,
+ 97, 77, 0, 26, 50, 99, 77, 0, 77, 0,
+ 215, 0, 0, 19, 59, 113, 76, 216, 203, 0,
+ 21, 107, 38, 0, 21, 107, 10, 107, 38, 0,
+ 22, 38, 0, 97, 38, 0, 0, 7, 0, 0,
+ 99, 0, 0, 221, 0, 222, 0, 221, 81, 222,
+ 0, 9, 59, 99, 76, 0, 115, 0, 223, 81,
+ 115, 0, 0, 225, 226, 0, 228, 76, 0, 0,
+ 229, 77, 227, 226, 0, 1, 76, 0, 0, 10,
+ 0, 229, 0, 229, 81, 10, 0, 230, 0, 229,
+ 81, 230, 0, 126, 123, 165, 143, 0, 126, 123,
+ 166, 143, 0, 126, 123, 182, 143, 0, 130, 123,
+ 166, 143, 0, 130, 123, 182, 143, 0, 0, 232,
+ 233, 0, 226, 0, 234, 76, 0, 3, 0, 234,
+ 81, 3, 0, 97, 0, 235, 81, 97, 0, 31,
+ 0, 241, 0, 239, 0, 240, 0, 251, 0, 261,
+ 0, 63, 0, 97, 0, 238, 81, 97, 0, 73,
+ 238, 77, 0, 74, 97, 97, 77, 0, 0, 0,
+ 61, 97, 253, 82, 242, 255, 78, 243, 268, 63,
+ 0, 0, 61, 97, 253, 244, 268, 63, 0, 0,
+ 0, 61, 97, 38, 97, 253, 82, 245, 255, 78,
+ 246, 268, 63, 0, 0, 61, 97, 38, 97, 253,
+ 247, 268, 63, 0, 0, 62, 97, 82, 248, 255,
+ 78, 0, 62, 97, 0, 0, 62, 97, 38, 97,
+ 82, 249, 255, 78, 0, 62, 97, 38, 97, 0,
+ 0, 61, 97, 59, 97, 76, 253, 250, 268, 63,
+ 0, 62, 97, 59, 97, 76, 0, 0, 71, 97,
+ 253, 252, 268, 63, 0, 0, 254, 0, 45, 238,
+ 45, 0, 255, 256, 257, 0, 257, 0, 69, 0,
+ 70, 0, 68, 0, 0, 257, 258, 77, 0, 257,
+ 77, 0, 132, 123, 259, 0, 183, 123, 259, 0,
+ 1, 0, 0, 260, 0, 259, 81, 260, 0, 163,
+ 0, 163, 38, 107, 0, 38, 107, 0, 0, 0,
+ 0, 48, 262, 278, 263, 279, 264, 194, 0, 0,
+ 0, 0, 49, 265, 278, 266, 279, 267, 194, 0,
+ 0, 0, 269, 270, 0, 273, 0, 89, 0, 270,
+ 273, 0, 0, 270, 271, 89, 0, 77, 0, 1,
+ 0, 0, 0, 48, 274, 278, 275, 272, 0, 0,
+ 0, 49, 276, 278, 277, 272, 0, 59, 181, 76,
+ 287, 0, 287, 0, 59, 181, 76, 288, 285, 0,
+ 288, 285, 0, 0, 77, 280, 0, 0, 281, 0,
+ 282, 0, 189, 0, 281, 282, 0, 282, 189, 0,
+ 126, 123, 283, 77, 0, 126, 77, 0, 130, 77,
+ 0, 284, 0, 283, 81, 284, 0, 165, 143, 0,
+ 166, 143, 0, 182, 143, 0, 0, 81, 10, 0,
+ 0, 81, 286, 228, 0, 289, 0, 291, 0, 288,
+ 291, 0, 3, 0, 4, 0, 72, 0, 290, 0,
+ 12, 0, 13, 0, 14, 0, 15, 0, 16, 0,
+ 17, 0, 18, 0, 19, 0, 20, 0, 21, 0,
+ 22, 0, 23, 0, 24, 0, 25, 0, 26, 0,
+ 27, 0, 11, 0, 28, 0, 29, 0, 6, 0,
+ 7, 0, 289, 38, 59, 181, 76, 97, 0, 289,
+ 38, 97, 0, 38, 59, 181, 76, 97, 0, 38,
+ 97, 0, 289, 0, 293, 0, 295, 0, 293, 295,
+ 0, 101, 0, 289, 38, 294, 0, 38, 294, 0,
+ 99, 0, 67, 0, 0, 0, 60, 298, 296, 299,
+ 292, 83, 0, 289, 0, 301, 0, 302, 0, 301,
+ 302, 0, 289, 38, 0, 38, 0, 64, 59, 300,
+ 76, 0, 71, 59, 97, 76, 0, 66, 59, 181,
+ 76, 0
+};
+
+#endif
+
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+ 239, 244, 258, 260, 260, 261, 263, 265, 266, 267,
+ 275, 279, 290, 295, 300, 302, 304, 305, 306, 311,
+ 318, 320, 325, 330, 336, 338, 343, 348, 354, 356,
+ 361, 368, 370, 371, 372, 375, 377, 379, 381, 383,
+ 385, 387, 391, 395, 398, 401, 404, 408, 410, 413,
+ 416, 420, 448, 454, 457, 460, 463, 465, 469, 473,
+ 477, 479, 482, 486, 513, 515, 517, 519, 521, 523,
+ 525, 527, 529, 531, 533, 535, 537, 539, 543, 545,
+ 549, 551, 554, 558, 560, 567, 570, 573, 579, 739,
+ 740, 742, 748, 750, 764, 787, 789, 791, 803, 817,
+ 819, 821, 823, 825, 827, 829, 834, 836, 842, 844,
+ 848, 850, 851, 861, 866, 868, 869, 870, 877, 883,
+ 888, 891, 899, 904, 906, 907, 908, 915, 926, 930,
+ 936, 941, 946, 951, 953, 955, 964, 967, 971, 973,
+ 975, 980, 984, 987, 991, 994, 996, 1008, 1011, 1013,
+ 1015, 1019, 1023, 1025, 1028, 1041, 1044, 1048, 1050, 1058,
+ 1059, 1060, 1064, 1066, 1071, 1073, 1075, 1081, 1082, 1083,
+ 1086, 1088, 1091, 1093, 1096, 1099, 1105, 1112, 1114, 1121,
+ 1128, 1131, 1138, 1141, 1145, 1148, 1152, 1157, 1160, 1164,
+ 1167, 1169, 1171, 1173, 1180, 1182, 1183, 1184, 1189, 1191,
+ 1196, 1204, 1209, 1213, 1216, 1218, 1223, 1226, 1228, 1230,
+ 1234, 1237, 1237, 1240, 1242, 1253, 1261, 1265, 1276, 1284,
+ 1291, 1293, 1298, 1301, 1306, 1308, 1310, 1317, 1319, 1320,
+ 1328, 1334, 1336, 1338, 1345, 1347, 1353, 1359, 1361, 1363,
+ 1365, 1372, 1374, 1377, 1382, 1384, 1388, 1390, 1392, 1394,
+ 1398, 1400, 1403, 1406, 1409, 1412, 1416, 1418, 1421, 1423,
+ 1427, 1430, 1435, 1437, 1439, 1443, 1467, 1474, 1479, 1485,
+ 1490, 1492, 1497, 1499, 1503, 1507, 1511, 1521, 1523, 1528,
+ 1533, 1536, 1540, 1543, 1547, 1550, 1553, 1556, 1560, 1563,
+ 1567, 1571, 1573, 1575, 1577, 1579, 1581, 1583, 1585, 1595,
+ 1603, 1605, 1607, 1611, 1613, 1616, 1619, 1632, 1634, 1639,
+ 1641, 1644, 1658, 1661, 1664, 1666, 1668, 1676, 1684, 1695,
+ 1700, 1703, 1717, 1726, 1730, 1734, 1738, 1744, 1748, 1753,
+ 1756, 1761, 1764, 1765, 1782, 1787, 1790, 1802, 1804, 1814,
+ 1824, 1825, 1833, 1836, 1848, 1852, 1869, 1879, 1888, 1893,
+ 1898, 1903, 1907, 1911, 1922, 1929, 1936, 1943, 1954, 1960,
+ 1963, 1968, 1991, 2025, 2050, 2081, 2096, 2107, 2111, 2115,
+ 2118, 2123, 2125, 2128, 2130, 2134, 2139, 2142, 2148, 2153,
+ 2158, 2160, 2169, 2170, 2176, 2178, 2188, 2190, 2194, 2197,
+ 2203, 2213, 2222, 2231, 2241, 2255, 2260, 2265, 2267, 2276,
+ 2279, 2284, 2287, 2291, 2299, 2301, 2302, 2303, 2304, 2305,
+ 2319, 2322, 2326, 2332, 2338, 2345, 2350, 2356, 2363, 2369,
+ 2375, 2380, 2386, 2393, 2399, 2405, 2411, 2419, 2425, 2431,
+ 2439, 2446, 2452, 2461, 2468, 2476, 2481, 2484, 2494, 2496,
+ 2499, 2501, 2502, 2505, 2510, 2511, 2528, 2535, 2541, 2545,
+ 2548, 2549, 2552, 2560, 2566, 2575, 2585, 2592, 2596, 2601,
+ 2610, 2617, 2621, 2631, 2633, 2634, 2636, 2638, 2639, 2640,
+ 2641, 2643, 2645, 2648, 2654, 2659, 2659, 2664, 2668, 2670,
+ 2676, 2681, 2686, 2695, 2697, 2703, 2705, 2708, 2710, 2711,
+ 2712, 2715, 2721, 2723, 2727, 2730, 2737, 2743, 2748, 2755,
+ 2760, 2765, 2770, 2777, 2781, 2784, 2790, 2792, 2793, 2794,
+ 2797, 2799, 2800, 2801, 2802, 2803, 2804, 2805, 2806, 2807,
+ 2808, 2809, 2810, 2811, 2812, 2813, 2814, 2815, 2816, 2817,
+ 2817, 2820, 2826, 2831, 2836, 2842, 2844, 2847, 2849, 2856,
+ 2868, 2873, 2879, 2881, 2887, 2891, 2892, 2898, 2900, 2903,
+ 2905, 2911, 2916, 2922, 2929, 2938
+};
+
+static const char * const yytname[] = { "$","error","$undefined.","IDENTIFIER",
+"TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF",
+"ENUM","STRUCT","UNION","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT",
+"BREAK","CONTINUE","RETURN","GOTO","ASM_KEYWORD","TYPEOF","ALIGNOF","ATTRIBUTE",
+"EXTENSION","LABEL","REALPART","IMAGPART","ASSIGN","'='","'?'","':'","OROR",
+"ANDAND","'|'","'^'","'&'","EQCOMPARE","ARITHCOMPARE","LSHIFT","RSHIFT","'+'",
+"'-'","'*'","'/'","'%'","UNARY","PLUSPLUS","MINUSMINUS","HYPERUNARY","POINTSAT",
+"'.'","'('","'['","INTERFACE","IMPLEMENTATION","END","SELECTOR","DEFS","ENCODE",
+"CLASSNAME","PUBLIC","PRIVATE","PROTECTED","PROTOCOL","OBJECTNAME","CLASS","ALIAS",
+"OBJC_STRING","')'","';'","'}'","'~'","'!'","','","'{'","']'","program","extdefs",
+"@1","@2","extdef","datadef","fndef","@3","@4","@5","@6","@7","@8","identifier",
+"unop","expr","exprlist","nonnull_exprlist","unary_expr","sizeof","alignof",
+"cast_expr","@9","expr_no_commas","@10","@11","@12","@13","@14","primary","@15",
+"string","objc_string","old_style_parm_decls","lineno_datadecl","datadecls",
+"datadecl","lineno_decl","decls","setspecs","setattrs","decl","typed_declspecs",
+"reserved_declspecs","typed_declspecs_no_prefix_attr","reserved_declspecs_no_prefix_attr",
+"declmods","declmods_no_prefix_attr","typed_typespecs","reserved_typespecquals",
+"typespec","typespecqual_reserved","initdecls","notype_initdecls","maybeasm",
+"initdcl","@16","notype_initdcl","@17","maybe_attribute","attributes","attribute",
+"attribute_list","attrib","any_word","init","@18","initlist_maybe_comma","initlist1",
+"initelt","@19","@20","@21","nested_function","@22","@23","notype_nested_function",
+"@24","@25","declarator","after_type_declarator","parm_declarator","notype_declarator",
+"structsp","@26","@27","@28","@29","maybecomma","maybecomma_warn","component_decl_list",
+"component_decl_list2","component_decl","components","component_declarator",
+"enumlist","enumerator","typename","absdcl","nonempty_type_quals","type_quals",
+"absdcl1","stmts","lineno_stmt_or_labels","xstmts","errstmt","pushlevel","maybe_label_decls",
+"label_decls","label_decl","compstmt_or_error","compstmt_start","compstmt","simple_if",
+"if_prefix","do_stmt_start","@30","save_filename","save_lineno","lineno_labeled_stmt",
+"lineno_stmt_or_label","stmt_or_label","stmt","@31","@32","@33","@34","@35",
+"@36","@37","all_iter_stmt","all_iter_stmt_simple","@38","label","maybe_type_qual",
+"xexpr","asm_operands","nonnull_asm_operands","asm_operand","asm_clobbers","parmlist",
+"@39","parmlist_1","@40","parmlist_2","parms","parm","parmlist_or_identifiers",
+"@41","parmlist_or_identifiers_1","identifiers","identifiers_or_typenames","extension",
+"objcdef","identifier_list","classdecl","aliasdecl","classdef","@42","@43","@44",
+"@45","@46","@47","@48","@49","@50","protocoldef","@51","protocolrefs","non_empty_protocolrefs",
+"ivar_decl_list","visibility_spec","ivar_decls","ivar_decl","ivars","ivar_declarator",
+"methoddef","@52","@53","@54","@55","@56","@57","methodprotolist","@58","methodprotolist2",
+"@59","semi_or_error","methodproto","@60","@61","@62","@63","methoddecl","optarglist",
+"myxdecls","mydecls","mydecl","myparms","myparm","optparmlist","@64","unaryselector",
+"keywordselector","selector","reservedwords","keyworddecl","messageargs","keywordarglist",
+"keywordexpr","keywordarg","receiver","objcmessageexpr","@65","@66","selectorarg",
+"keywordnamelist","keywordname","objcselectorexpr","objcprotocolexpr","objcencodeexpr",
+""
+};
+#endif
+
+static const short yyr1[] = { 0,
+ 84, 84, 86, 85, 87, 85, 88, 88, 88, 88,
+ 88, 89, 89, 89, 89, 89, 89, 89, 89, 91,
+ 92, 90, 90, 93, 94, 90, 90, 95, 96, 90,
+ 90, 97, 97, 97, 97, 98, 98, 98, 98, 98,
+ 98, 98, 99, 100, 100, 101, 101, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 103, 104,
+ 105, 105, 106, 105, 107, 107, 107, 107, 107, 107,
+ 107, 107, 107, 107, 107, 107, 107, 108, 107, 109,
+ 107, 110, 111, 107, 112, 107, 107, 107, 113, 113,
+ 113, 113, 113, 114, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 115, 115, 116, 116,
+ 117, 117, 117, 118, 119, 119, 119, 119, 120, 120,
+ 120, 120, 121, 122, 122, 122, 122, 123, 124, 125,
+ 125, 125, 125, 125, 125, 125, 126, 126, 127, 127,
+ 127, 127, 128, 128, 129, 129, 129, 130, 130, 130,
+ 130, 131, 131, 131, 131, 132, 132, 133, 133, 134,
+ 134, 134, 134, 134, 134, 134, 134, 135, 135, 135,
+ 136, 136, 137, 137, 138, 138, 140, 139, 139, 142,
+ 141, 141, 143, 143, 144, 144, 145, 146, 146, 147,
+ 147, 147, 147, 147, 148, 148, 148, 148, 149, 150,
+ 149, 149, 151, 151, 152, 152, 153, 154, 153, 153,
+ 155, 153, 156, 153, 158, 159, 157, 161, 162, 160,
+ 163, 163, 164, 164, 164, 164, 164, 164, 164, 164,
+ 165, 165, 165, 165, 165, 165, 166, 166, 166, 166,
+ 166, 166, 166, 168, 167, 167, 167, 169, 167, 167,
+ 167, 170, 167, 171, 167, 167, 172, 172, 173, 173,
+ 174, 174, 175, 175, 175, 175, 176, 176, 176, 176,
+ 176, 176, 177, 177, 178, 178, 178, 179, 179, 179,
+ 180, 180, 181, 181, 182, 182, 183, 183, 184, 184,
+ 185, 185, 185, 185, 185, 185, 185, 185, 185, 186,
+ 187, 187, 187, 188, 188, 189, 190, 191, 191, 192,
+ 192, 193, 194, 194, 195, 196, 196, 196, 196, 197,
+ 197, 198, 200, 199, 201, 202, 203, 203, 204, 205,
+ 205, 206, 206, 206, 207, 206, 206, 206, 208, 209,
+ 206, 206, 206, 210, 211, 212, 206, 213, 206, 206,
+ 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
+ 214, 216, 215, 217, 217, 217, 217, 218, 218, 219,
+ 219, 220, 220, 221, 221, 222, 223, 223, 225, 224,
+ 226, 227, 226, 226, 228, 228, 228, 228, 229, 229,
+ 230, 230, 230, 230, 230, 232, 231, 233, 233, 234,
+ 234, 235, 235, 236, 237, 237, 237, 237, 237, 237,
+ 238, 238, 239, 240, 242, 243, 241, 244, 241, 245,
+ 246, 241, 247, 241, 248, 241, 241, 249, 241, 241,
+ 250, 241, 241, 252, 251, 253, 253, 254, 255, 255,
+ 256, 256, 256, 257, 257, 257, 258, 258, 258, 259,
+ 259, 259, 260, 260, 260, 262, 263, 264, 261, 265,
+ 266, 267, 261, 268, 269, 268, 270, 270, 270, 271,
+ 270, 272, 272, 274, 275, 273, 276, 277, 273, 278,
+ 278, 278, 278, 279, 279, 280, 280, 281, 281, 281,
+ 281, 282, 282, 282, 283, 283, 284, 284, 284, 285,
+ 285, 286, 285, 287, 288, 288, 289, 289, 289, 289,
+ 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
+ 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
+ 290, 291, 291, 291, 291, 292, 292, 293, 293, 294,
+ 295, 295, 296, 296, 298, 299, 297, 300, 300, 301,
+ 301, 302, 302, 303, 304, 305
+};
+
+static const short yyr2[] = { 0,
+ 0, 1, 0, 2, 0, 3, 1, 1, 1, 5,
+ 2, 3, 4, 4, 2, 2, 2, 2, 1, 0,
+ 0, 7, 4, 0, 0, 7, 4, 0, 0, 6,
+ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 1, 1, 3, 1, 2, 2,
+ 2, 2, 2, 4, 2, 4, 2, 2, 1, 1,
+ 1, 4, 0, 7, 1, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 0, 4, 0,
+ 4, 0, 0, 7, 0, 5, 3, 3, 1, 1,
+ 1, 3, 3, 0, 4, 4, 4, 3, 3, 2,
+ 2, 1, 1, 1, 1, 1, 1, 2, 1, 2,
+ 0, 1, 2, 3, 1, 1, 2, 2, 4, 4,
+ 2, 2, 3, 1, 1, 2, 2, 0, 0, 4,
+ 4, 3, 3, 2, 2, 2, 2, 3, 0, 2,
+ 2, 2, 2, 3, 0, 2, 2, 1, 1, 2,
+ 2, 1, 1, 2, 2, 2, 3, 0, 2, 1,
+ 1, 1, 2, 2, 1, 4, 4, 1, 1, 1,
+ 1, 3, 1, 3, 0, 4, 0, 6, 3, 0,
+ 6, 3, 0, 1, 1, 2, 6, 1, 3, 0,
+ 1, 4, 6, 4, 1, 1, 1, 1, 1, 0,
+ 4, 1, 0, 2, 1, 3, 1, 0, 4, 1,
+ 0, 4, 0, 5, 0, 0, 5, 0, 0, 5,
+ 1, 1, 3, 3, 4, 3, 3, 3, 1, 1,
+ 3, 4, 3, 3, 3, 1, 3, 3, 3, 4,
+ 3, 3, 1, 0, 7, 5, 2, 0, 7, 5,
+ 2, 0, 8, 0, 7, 2, 0, 1, 0, 1,
+ 1, 2, 0, 3, 2, 4, 3, 1, 3, 1,
+ 1, 2, 1, 3, 4, 6, 5, 1, 3, 1,
+ 1, 3, 2, 2, 0, 1, 1, 2, 0, 2,
+ 3, 3, 2, 3, 4, 3, 2, 3, 2, 1,
+ 1, 2, 2, 0, 1, 2, 0, 0, 1, 1,
+ 2, 3, 1, 2, 1, 2, 6, 5, 5, 2,
+ 2, 4, 0, 4, 0, 0, 3, 4, 3, 1,
+ 1, 1, 1, 2, 0, 4, 1, 3, 0, 0,
+ 7, 5, 2, 0, 0, 0, 12, 0, 6, 2,
+ 2, 2, 3, 6, 8, 10, 12, 3, 4, 1,
+ 1, 0, 6, 3, 5, 2, 2, 0, 1, 0,
+ 1, 0, 1, 1, 3, 4, 1, 3, 0, 2,
+ 2, 0, 4, 2, 0, 1, 1, 3, 1, 3,
+ 4, 4, 4, 4, 4, 0, 2, 1, 2, 1,
+ 3, 1, 3, 1, 1, 1, 1, 1, 1, 1,
+ 1, 3, 3, 4, 0, 0, 10, 0, 6, 0,
+ 0, 12, 0, 8, 0, 6, 2, 0, 8, 4,
+ 0, 9, 5, 0, 6, 0, 1, 3, 3, 1,
+ 1, 1, 1, 0, 3, 2, 3, 3, 1, 0,
+ 1, 3, 1, 3, 2, 0, 0, 0, 7, 0,
+ 0, 0, 7, 0, 0, 2, 1, 1, 2, 0,
+ 3, 1, 1, 0, 0, 5, 0, 0, 5, 4,
+ 1, 5, 2, 0, 2, 0, 1, 1, 1, 2,
+ 2, 4, 2, 2, 1, 3, 2, 2, 2, 0,
+ 2, 0, 3, 1, 1, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 6, 3, 5, 2, 1, 1, 1, 2, 1,
+ 3, 2, 1, 1, 0, 0, 6, 1, 1, 1,
+ 2, 2, 1, 4, 4, 4
+};
+
+static const short yydefact[] = { 3,
+ 5, 0, 0, 0, 162, 153, 160, 152, 0, 0,
+ 0, 0, 0, 0, 404, 0, 456, 460, 0, 0,
+ 410, 436, 0, 436, 0, 0, 19, 4, 8, 7,
+ 0, 128, 128, 148, 139, 149, 185, 161, 0, 9,
+ 406, 407, 405, 408, 165, 409, 6, 17, 18, 32,
+ 33, 35, 34, 254, 256, 263, 247, 263, 251, 0,
+ 0, 0, 411, 0, 0, 0, 436, 427, 163, 437,
+ 436, 164, 0, 0, 243, 289, 0, 0, 173, 129,
+ 0, 16, 0, 15, 0, 150, 139, 151, 155, 154,
+ 137, 186, 11, 0, 252, 0, 0, 0, 244, 0,
+ 248, 89, 90, 107, 59, 60, 0, 0, 0, 36,
+ 38, 37, 0, 39, 40, 0, 545, 0, 0, 0,
+ 109, 41, 42, 0, 0, 43, 61, 0, 0, 65,
+ 46, 48, 91, 106, 0, 102, 103, 104, 105, 287,
+ 0, 285, 158, 0, 285, 190, 438, 0, 507, 508,
+ 530, 531, 527, 511, 512, 513, 514, 515, 516, 517,
+ 518, 519, 520, 521, 522, 523, 524, 525, 526, 528,
+ 529, 0, 0, 509, 457, 481, 500, 504, 510, 505,
+ 461, 0, 0, 418, 0, 0, 425, 434, 413, 0,
+ 0, 0, 12, 0, 0, 31, 0, 396, 0, 0,
+ 183, 229, 289, 0, 230, 0, 171, 129, 0, 221,
+ 222, 0, 0, 138, 141, 168, 169, 140, 142, 170,
+ 280, 281, 259, 278, 0, 0, 183, 271, 265, 128,
+ 262, 128, 0, 263, 183, 263, 57, 58, 52, 49,
+ 0, 0, 0, 0, 0, 0, 0, 0, 51, 0,
+ 0, 0, 53, 0, 55, 0, 0, 82, 80, 78,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 100, 101, 0, 0, 44, 0, 108, 110,
+ 50, 166, 289, 379, 0, 283, 286, 156, 167, 288,
+ 158, 284, 196, 197, 198, 195, 0, 188, 191, 412,
+ 0, 535, 0, 484, 502, 483, 0, 506, 0, 484,
+ 436, 0, 415, 465, 430, 0, 444, 465, 414, 290,
+ 239, 238, 174, 175, 242, 0, 237, 0, 241, 0,
+ 0, 29, 0, 325, 116, 326, 182, 184, 0, 0,
+ 14, 0, 0, 23, 0, 183, 396, 0, 13, 27,
+ 0, 0, 260, 0, 259, 0, 246, 325, 264, 325,
+ 272, 0, 250, 0, 93, 92, 315, 307, 0, 0,
+ 544, 543, 546, 553, 548, 0, 549, 550, 0, 0,
+ 10, 47, 0, 0, 88, 87, 0, 0, 0, 0,
+ 76, 77, 75, 74, 73, 71, 72, 66, 67, 68,
+ 69, 70, 99, 98, 0, 45, 0, 293, 0, 297,
+ 0, 299, 0, 379, 0, 159, 157, 0, 190, 44,
+ 0, 0, 0, 458, 501, 385, 0, 533, 462, 423,
+ 436, 444, 0, 0, 428, 433, 0, 0, 0, 0,
+ 0, 400, 386, 128, 128, 398, 0, 387, 389, 397,
+ 0, 240, 306, 0, 118, 113, 117, 0, 180, 227,
+ 223, 172, 228, 21, 179, 224, 226, 0, 25, 282,
+ 279, 183, 0, 266, 267, 273, 326, 269, 183, 183,
+ 316, 308, 95, 63, 62, 0, 552, 554, 0, 551,
+ 556, 555, 54, 56, 0, 0, 81, 79, 96, 97,
+ 292, 291, 380, 298, 294, 296, 0, 187, 189, 89,
+ 0, 0, 480, 500, 128, 0, 489, 485, 487, 0,
+ 0, 503, 387, 0, 0, 420, 465, 431, 0, 419,
+ 474, 477, 468, 0, 128, 128, 470, 467, 444, 443,
+ 441, 442, 426, 444, 449, 446, 128, 128, 0, 435,
+ 176, 384, 285, 285, 381, 382, 0, 399, 0, 0,
+ 30, 313, 114, 128, 128, 145, 0, 0, 177, 225,
+ 0, 255, 183, 325, 0, 245, 249, 0, 0, 309,
+ 310, 0, 0, 536, 0, 537, 538, 83, 86, 295,
+ 192, 0, 194, 534, 482, 493, 285, 494, 490, 491,
+ 459, 0, 463, 444, 0, 465, 416, 0, 0, 175,
+ 0, 0, 0, 469, 0, 0, 450, 450, 445, 236,
+ 289, 379, 129, 183, 183, 183, 289, 183, 183, 0,
+ 388, 390, 401, 314, 121, 0, 122, 0, 145, 143,
+ 202, 200, 199, 181, 22, 0, 26, 253, 274, 0,
+ 183, 402, 0, 0, 0, 325, 0, 0, 125, 326,
+ 301, 311, 210, 89, 0, 208, 0, 207, 0, 257,
+ 205, 540, 542, 0, 547, 0, 539, 0, 0, 183,
+ 183, 183, 0, 495, 532, 0, 424, 0, 465, 475,
+ 478, 471, 429, 0, 453, 447, 451, 448, 293, 0,
+ 396, 0, 391, 392, 393, 293, 394, 395, 383, 0,
+ 0, 144, 147, 146, 0, 178, 183, 0, 275, 312,
+ 0, 318, 127, 126, 305, 0, 319, 303, 326, 302,
+ 0, 0, 0, 211, 64, 0, 204, 541, 84, 193,
+ 497, 498, 499, 492, 285, 421, 432, 0, 0, 0,
+ 455, 0, 0, 234, 289, 235, 231, 233, 0, 119,
+ 120, 0, 277, 183, 403, 317, 0, 162, 0, 339,
+ 323, 0, 0, 0, 0, 0, 0, 0, 0, 368,
+ 436, 436, 360, 0, 0, 123, 128, 128, 332, 337,
+ 0, 0, 329, 330, 333, 361, 331, 0, 213, 0,
+ 0, 206, 496, 465, 417, 473, 472, 476, 479, 454,
+ 452, 0, 232, 201, 276, 0, 0, 325, 370, 0,
+ 0, 366, 350, 351, 352, 0, 0, 0, 369, 0,
+ 367, 334, 134, 0, 135, 0, 0, 321, 326, 320,
+ 343, 0, 136, 0, 209, 212, 0, 0, 0, 0,
+ 371, 48, 0, 0, 0, 364, 353, 0, 358, 0,
+ 0, 132, 215, 0, 133, 218, 338, 325, 0, 0,
+ 214, 422, 322, 0, 324, 362, 344, 348, 0, 359,
+ 0, 130, 0, 131, 0, 336, 327, 325, 0, 340,
+ 325, 370, 325, 365, 372, 0, 216, 219, 328, 342,
+ 325, 363, 0, 349, 0, 0, 373, 374, 354, 0,
+ 0, 341, 345, 0, 372, 0, 0, 217, 220, 370,
+ 0, 0, 355, 375, 0, 376, 0, 0, 346, 377,
+ 0, 356, 325, 0, 0, 347, 357, 378, 0, 0,
+ 0
+};
+
+static const short yydefgoto[] = { 939,
+ 1, 2, 3, 28, 29, 30, 345, 568, 351, 571,
+ 200, 454, 667, 124, 242, 405, 126, 127, 128, 129,
+ 130, 582, 131, 390, 389, 387, 678, 388, 132, 243,
+ 133, 134, 332, 333, 334, 563, 655, 656, 31, 195,
+ 786, 444, 91, 564, 640, 445, 34, 142, 288, 35,
+ 218, 206, 78, 201, 207, 646, 79, 567, 337, 338,
+ 37, 297, 298, 299, 644, 715, 669, 670, 671, 733,
+ 801, 844, 862, 883, 910, 865, 885, 911, 324, 210,
+ 680, 211, 38, 234, 236, 225, 94, 737, 354, 97,
+ 98, 231, 475, 476, 223, 224, 144, 682, 145, 191,
+ 287, 657, 658, 726, 335, 482, 579, 580, 581, 561,
+ 368, 562, 790, 791, 792, 818, 839, 458, 840, 661,
+ 793, 794, 868, 817, 901, 892, 920, 933, 893, 795,
+ 796, 891, 797, 830, 853, 906, 907, 908, 931, 410,
+ 411, 446, 630, 447, 448, 449, 327, 328, 450, 451,
+ 653, 135, 40, 64, 41, 42, 43, 432, 689, 314,
+ 604, 804, 527, 317, 539, 606, 44, 318, 69, 45,
+ 437, 544, 438, 549, 696, 697, 46, 65, 304, 521,
+ 66, 310, 525, 433, 434, 537, 613, 808, 538, 608,
+ 749, 609, 750, 175, 424, 518, 519, 520, 683, 684,
+ 306, 426, 176, 177, 178, 179, 180, 585, 586, 673,
+ 587, 373, 136, 245, 486, 376, 377, 378, 137, 138,
+ 139
+};
+
+static const short yypact[] = { 120,
+ 131, 2895, 2895, 468,-32768,-32768,-32768,-32768, 98, 118,
+ 257, 110, 122, 132,-32768, 266,-32768,-32768, 266, 266,
+-32768, 158, 266, 158, 266, 266,-32768,-32768,-32768,-32768,
+ 234, 153, 2375, 497,-32768, 218,-32768,-32768, 2895,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, 172, 210, 203, 210, 221, 2604,
+ 2442, 254,-32768, 61, 3182, 3182, 81, 133,-32768,-32768,
+ 158,-32768, 151, 266,-32768,-32768, 234, 253,-32768, 218,
+ 1662,-32768, 540,-32768, 234, 497,-32768, 218,-32768,-32768,
+ 879,-32768,-32768, 94,-32768, 263, 289, 1593,-32768, 298,
+-32768,-32768,-32768,-32768,-32768,-32768, 2604, 2604, 266,-32768,
+-32768,-32768, 2604,-32768,-32768, 933,-32768, 278, 323, 326,
+-32768,-32768,-32768, 2604, 331, 361,-32768, 2658, 2712,-32768,
+ 3553, 1169, 403, 370, 2604,-32768,-32768,-32768,-32768,-32768,
+ 396, 267,-32768, 402, 3336, 302,-32768, 266,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768, 129, 3459,-32768,-32768,-32768, 2336, 457,-32768,-32768,
+-32768, 266, 266, 449, 266, 266,-32768,-32768,-32768, 461,
+ 642, 54,-32768, 540, 234,-32768, 474,-32768, 1805, 683,
+ 218,-32768,-32768, 540,-32768, 259,-32768, 218, 1760, 526,
+ 529, 318, 1681, 879,-32768,-32768,-32768,-32768, 218,-32768,
+-32768, 505, 470,-32768, 94, 491, 218,-32768,-32768, 525,
+ 486, 3078, 374, 210, 218, 210,-32768,-32768,-32768,-32768,
+ 490, 499, 495, 503, 2496, 3244, 3459, 266,-32768, 517,
+ 2604, 933,-32768, 933,-32768, 2604, 2604, 558,-32768,-32768,
+ 2604, 2604, 2604, 2604, 2604, 2604, 2604, 2604, 2604, 2604,
+ 2604, 2604,-32768,-32768, 266, 266, 2604, 2604,-32768,-32768,
+-32768,-32768,-32768, 267, 1864,-32768, 547, 711,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768, 29,-32768, 539,-32768,
+ 3459,-32768, 537, 542, 618,-32768, 457,-32768, 147, 542,
+ 158, 559,-32768, 574, 573, 585,-32768, 574,-32768,-32768,
+ 529,-32768,-32768, 635, 529, 654,-32768, 3048,-32768, 582,
+ 589,-32768, 276, 82,-32768,-32768, 631, 218, 269, 219,
+-32768, 540, 540,-32768, 683, 218,-32768, 1923,-32768,-32768,
+ 683, 2604, 266, 591, 470, 595,-32768,-32768,-32768,-32768,
+-32768, 592,-32768, 596,-32768,-32768,-32768, 599, 597, 2256,
+-32768,-32768,-32768,-32768, 640, 606, 3244,-32768, 607, 610,
+-32768, 3553, 615, 617, 3553, 3553, 2604, 656, 2604, 2604,
+ 2834, 2942, 880, 784, 1653, 900, 900, 478, 478,-32768,
+-32768,-32768,-32768,-32768, 622, 361, 616, 456, 242,-32768,
+ 3067,-32768, 621,-32768, 1982,-32768, 711, 624, 302, 2766,
+ 632, 3272, 851,-32768,-32768, 3347, 3459,-32768,-32768, 628,
+ 158,-32768, 658, 2970,-32768,-32768, 347, 2843, 666, 84,
+ 643,-32768,-32768,-32768, 3422,-32768, 659, 327,-32768,-32768,
+ 176,-32768,-32768, 86,-32768,-32768,-32768, 3441,-32768, 526,
+-32768,-32768, 526,-32768, 701,-32768,-32768, 660,-32768, 3553,
+-32768, 218, 663,-32768, 661,-32768,-32768, 661, 218, 218,
+-32768, 713,-32768,-32768,-32768, 3308,-32768,-32768, 640,-32768,
+-32768,-32768,-32768,-32768, 708, 2604, 2417, 1396,-32768,-32768,
+ 547,-32768,-32768,-32768,-32768,-32768, 668,-32768,-32768, 211,
+ 681, 266,-32768, 2336, 676, 3097,-32768,-32768, 3422, 1779,
+ 86,-32768, 679, 700, 86,-32768, 574,-32768, 352,-32768,
+-32768,-32768,-32768, 234, 153, 2375, 262,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768, 3478, 705,-32768,
+-32768,-32768, 464, 93,-32768,-32768, 3411,-32768, 780, 495,
+-32768,-32768,-32768, 707, 726,-32768, 840, 86,-32768,-32768,
+ 86,-32768, 218,-32768, 368,-32768,-32768, 266, 1102, 713,
+-32768, 1422, 2604, 750, 706, 3308,-32768,-32768, 1475,-32768,
+-32768, 2604,-32768,-32768,-32768,-32768, 464,-32768,-32768,-32768,
+-32768, 266,-32768,-32768, 729, 574,-32768, 3182, 3182, 76,
+ 540, 234, 2998,-32768, 430, 2861, 1377, 1377,-32768,-32768,
+-32768, 93, 218, 238, 330, 218,-32768, 330, 218, 3067,
+-32768,-32768,-32768,-32768,-32768, 540,-32768, 234,-32768, 767,
+-32768,-32768, 3553,-32768,-32768, 840,-32768,-32768,-32768, 2604,
+ 212,-32768, 377, 545, 1022, 716, 717, 1182,-32768,-32768,
+-32768,-32768,-32768, 758, 266,-32768, 762, 3553, 735, 737,
+-32768, 361,-32768, 2604,-32768, 750,-32768, 2604, 273, 238,
+ 330, 218, 383,-32768,-32768, 442,-32768, 760, 574,-32768,
+-32768,-32768,-32768, 2604, 789, 757,-32768, 757, 588, 677,
+-32768, 2041,-32768,-32768,-32768, 594,-32768,-32768,-32768, 389,
+ 416, 767,-32768,-32768, 1422,-32768, 3186, 2604,-32768,-32768,
+ 266,-32768,-32768,-32768,-32768, 764,-32768,-32768,-32768,-32768,
+ 2122, 808, 1422,-32768,-32768, 1502,-32768,-32768, 1475,-32768,
+-32768,-32768,-32768,-32768, 464,-32768,-32768, 782, 72, 72,
+ 3553, 2604, 1377, 583,-32768, 583,-32768,-32768, 763,-32768,
+-32768, 775,-32768, 3186,-32768,-32768, 2202, 816, 800,-32768,
+-32768, 802, 813, 2604, 829, 798, 805, 2550, 429, 890,
+ 79, 141,-32768, 849, 824,-32768, 825, 3147,-32768, 887,
+ 1262, 103,-32768,-32768,-32768,-32768,-32768, 2364,-32768, 827,
+ 1582,-32768,-32768, 574,-32768,-32768,-32768,-32768,-32768, 3553,
+-32768, 601,-32768,-32768,-32768, 2604, 848,-32768, 2604, 2604,
+ 3517,-32768,-32768,-32768,-32768, 831, 2604, 833,-32768, 853,
+-32768,-32768,-32768, 540,-32768, 234, 1342,-32768,-32768,-32768,
+-32768, 2604,-32768, 1582,-32768,-32768, 854, 845, 2604, 899,
+-32768, 752, 866, 878, 2604,-32768,-32768, 881,-32768, 2604,
+ 432,-32768, 320, 440,-32768, 332,-32768,-32768, 2202, 883,
+-32768,-32768,-32768, 889,-32768,-32768,-32768,-32768, 3535,-32768,
+ 52,-32768, 683,-32768, 683,-32768,-32768,-32768, 886,-32768,
+-32768, 2604,-32768,-32768, 946, 891,-32768,-32768,-32768,-32768,
+-32768,-32768, 892,-32768, 898, 69, 893,-32768,-32768, 495,
+ 495,-32768,-32768, 2604, 946, 894, 946,-32768,-32768, 2604,
+ 901, 145,-32768,-32768, 903,-32768, 654, 907,-32768, 403,
+ 303,-32768,-32768, 908, 654,-32768,-32768, 403, 970, 975,
+-32768
+};
+
+static const short yypgoto[] = {-32768,
+-32768,-32768,-32768, 192, -367,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, -9,-32768, -52, 560, -231, 530,-32768,-32768,
+ -54,-32768, 220,-32768,-32768,-32768,-32768,-32768, 167,-32768,
+ -295,-32768, -312, 655,-32768,-32768, 334,-32768, 17, -195,
+ 193, 16, 909,-32768, 356, 21, -11, -61, 710, 11,
+ -276, -575, -58, -206, -118,-32768,-32768,-32768, 196, 3,
+ -6,-32768, 579,-32768, 357,-32768, -604,-32768, -657,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -68, -135,
+ -489, 14, -66,-32768,-32768,-32768,-32768,-32768, 647, 19,
+-32768, 773, 649, 433, 785, 664, -27, -79, -55, -168,
+ -226, 355,-32768,-32768, -285,-32768,-32768,-32768, 434, -413,
+-32768, -205,-32768,-32768,-32768,-32768, -122, -415, -734, 358,
+-32768, 149,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, 150,-32768, -658, 105,-32768, 107,-32768, 608,
+-32768, -359,-32768, 612, 633, 475, -307,-32768,-32768,-32768,
+-32768, 18,-32768, 1029,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -20, 4,
+ -364,-32768, 513,-32768, 443, 305,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768, -286,-32768,-32768,-32768, 310, 531,-32768,
+-32768,-32768,-32768, -25, 753,-32768,-32768, 550,-32768, 321,
+ 564,-32768, 651, 652, -121,-32768, -148,-32768,-32768, 405,
+ 494,-32768,-32768,-32768,-32768,-32768,-32768, 714,-32768,-32768,
+-32768
+};
+
+
+#define YYLAST 3605
+
+
+static const short yytable[] = { 55,
+ 57, 59, 346, 72, 36, 36, 63, 125, 141, 67,
+ 68, 416, 343, 71, 209, 63, 74, 32, 32, 39,
+ 39, 86, 33, 33, 220, 70, 212, 70, 308, 92,
+ 440, 439, 464, 80, 339, 88, 230, 369, 469, 466,
+ 181, 36, 232, 87, 81, 406, 184, 455, 83, 85,
+ 188, 503, 237, 238, 32, 307, 39, 409, 240, 33,
+ 710, 575, 286, 624, 190, 292, 533, 529, 340, 249,
+ 70, 143, 806, 92, 70, 323, 100, 336, 802, 80,
+ 281, 92, -112, 850, 222, 208, 560, 80, 244, 895,
+ 192, 456, 279, 219, 221, 75, 50, 51, 213, 239,
+ 50, 51, 197, 841, 418, 147, 915, 601, 143, 419,
+ 762, 603, 198, 199, 408, 233, -35, 346, 182, -1,
+ 50, 51, 14, 16, 375, 16, 143, 896, 800, 322,
+ -2, 50, 51, 886, 198, 199, 296, 517, 300, 183,
+ 416, 148, 627, 846, 916, 303, 330, 220, 807, 50,
+ 51, 622, 285, 899, 645, 291, 902, 647, 904, 551,
+ 52, 842, 302, -112, 52, 53, 912, 367, 60, 53,
+ 185, 230, 311, 312, 615, 315, 316, 232, -34, 54,
+ 61, 501, 927, 143, 52, 16, 871, 301, 406, 53,
+ 62, 186, 372, 80, 47, 52, 208, 80, 936, 56,
+ 53, 92, 16, 460, 321, 427, 208, 463, 325, 754,
+ 756, 336, 92, 52, 187, 222, 219, 192, 53, 379,
+ 928, 220, 336, 462, 383, 407, 384, 189, 336, 82,
+ 93, 148, 413, 903, 600, 477, 75, 477, 380, 686,
+ 605, 14, 291, 143, 731, 692, 358, 14, 360, 718,
+ 233, 558, 362, 95, 364, 489, 559, 143, 861, 50,
+ 51, 925, 143, 14, 143, 403, 404, 14, 50, 51,
+ 709, 75, 202, 421, 96, 320, 331, 347, 348, -115,
+ -115, -115, -115, 76, 99, -115, 591, -115, -115, -115,
+ 430, 592, 77, 659, 461, 468, 701, 702, 14, 428,
+ 414, 415, 101, -115, 50, 51, 293, 294, 295, 531,
+ 532, 143, 146, 767, 70, 485, 283, 502, 203, 688,
+ -115, 226, 754, 52, -466, 284, 285, 204, 53, 193,
+ 36, 92, 52, 194, 495, 341, 246, 53, 58, 342,
+ 205, 208, -115, 222, 208, 208, 197, -115, 740, -175,
+ 220, 672, 321, 251, 634, -175, 325, -115, 197, 14,
+ 679, -175, 507, 714, 584, 308, 227, -175, 52, 723,
+ 75, 202, 728, 53, 228, 235, 547, 5, 934, 7,
+ 140, 247, 548, 935, 248, 9, 10, 11, 198, 199,
+ 198, 199, 307, 757, 349, 409, -175, 14, 194, 524,
+ -175, 13, 748, 556, 15, 650, 250, 557, -175, 296,
+ 528, 279, -175, 36, 540, 541, 542, 203, 16, 540,
+ 541, 542, 357, 869, 543, 36, 204, 700, 36, 607,
+ 363, 50, 51, 86, 70, 714, 36, 143, 515, 205,
+ 22, 251, 672, 516, 280, 24, 565, 88, 143, 535,
+ 534, 477, 699, 720, 536, 87, 660, 721, 706, 744,
+ 553, 554, 320, 745, 676, 760, 75, 620, 566, 342,
+ 382, 282, 501, 626, 629, 385, 386, 289, 827, 501,
+ 391, 392, 393, 394, 395, 396, 397, 398, 399, 400,
+ 401, 402, 761, 14, 309, 52, 194, 540, 541, 542,
+ 53, 89, 594, 90, 86, 283, 651, 693, 882, 540,
+ 541, 542, 342, 621, 284, 285, 884, 847, 88, 746,
+ 194, 36, 622, 285, 86, 789, 87, 270, 271, 272,
+ 313, 597, 326, 660, 515, 729, 80, 319, 88, 516,
+ 352, 465, 75, 202, 48, 49, 87, 610, 695, 695,
+ 353, 611, 612, 212, 547, 623, 80, 356, 291, 36,
+ 548, 789, 359, 617, 618, 365, 625, 628, 652, 14,
+ 897, 470, 898, 220, 366, 639, 367, 208, 370, 711,
+ 636, 638, 690, 691, 347, 348, 812, 198, 199, 203,
+ 75, 620, 685, 381, 320, -85, 75, 420, 204, 623,
+ 320, -268, -268, 75, 620, 414, 415, 320, 497, 498,
+ 681, 205, 422, 208, 80, 36, 92, 14, 423, 208,
+ 208, 453, 722, 14, 80, 610, 143, 425, 535, 534,
+ 14, 930, 36, 536, 431, 192, -464, 621, 208, 938,
+ 80, 701, 702, 627, 75, 220, 622, 285, 320, 759,
+ 755, 610, 622, 285, 435, 732, 346, 253, 255, 77,
+ 436, 197, 104, 789, 452, 453, 459, 572, 472, 479,
+ 474, 14, 483, 480, 576, 577, 481, 487, 785, 75,
+ 620, 488, 491, 331, 695, 492, -325, -325, -325, -325,
+ 493, 76, 494, 496, -325, -325, -325, 499, 500, 508,
+ 77, 623, 623, 504, 918, 919, 14, 512, 80, 526,
+ -325, 765, 321, 325, 785, 589, 216, 217, 552, 321,
+ 530, 784, 9, 10, 11, 826, 755, -325, 550, 5,
+ 89, 7, 90, 36, 555, 77, 569, 9, 10, 11,
+ 573, 574, 570, 281, 578, 588, 787, 623, 798, -325,
+ 590, 788, 596, 13, -325, 208, 593, 784, 681, 557,
+ 336, 72, 336, 848, -111, 863, 851, 854, 648, 828,
+ 16, 713, 216, 217, 858, 602, 86, 864, 9, 10,
+ 11, 619, 633, 635, 70, 70, 643, 674, 675, 870,
+ 88, 687, 22, -304, 727, -32, 874, 24, 87, 734,
+ 36, 668, 637, 834, 836, 273, 274, 881, 275, 276,
+ 277, 278, 735, 787, 623, 798, 785, 736, 788, 703,
+ 704, 705, 747, 707, 708, 321, 752, 876, 265, 266,
+ 267, 268, 269, 270, 271, 272, 208, 753, 80, 851,
+ 641, 766, 102, 799, 805, 813, 719, 103, 104, 866,
+ 105, 331, 814, -33, 5, 6, 7, 8, 816, 784,
+ 819, 921, 9, 10, 11, 643, 822, 851, 106, 717,
+ 15, 820, 107, 108, 823, 741, 742, 743, 13, 109,
+ 14, 824, 110, 215, 216, 217, 831, 111, 112, 113,
+ 9, 10, 11, 114, 115, 16, 829, 739, 116, 117,
+ 832, 833, 837, 118, 845, 119, 849, 857, 14, 859,
+ 120, 860, 763, 751, 121, 875, 872, 22, 122, 123,
+ 873, 642, 24, 264, 265, 266, 267, 268, 269, 270,
+ 271, 272, -486, 241, 668, 102, 5, 764, 7, 140,
+ 103, 104, 877, 105, 9, 10, 11, 268, 269, 270,
+ 271, 272, 668, 878, 905, 668, 914, 880, 889, 815,
+ 13, 106, 900, 15, 890, 107, 108, 909, 913, 940,
+ 923, 810, 109, 917, 941, 110, 926, 16, 929, 511,
+ 111, 112, 113, 932, 937, 852, 114, 115, 457, 724,
+ 843, 116, 117, 821, 712, 214, 118, 509, 119, 22,
+ 417, 473, 716, 120, 24, 361, 649, 121, 478, 355,
+ 725, 122, 123, 662, -94, 730, 471, 887, 888, 922,
+ 668, 505, 331, 924, -124, -124, -124, -124, -124, -124,
+ -124, 632, -124, -124, -124, -124, -124, 522, -124, -124,
+ -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
+ -124, -124, -124, 73, -124, -124, 616, 811, 523, 809,
+ 698, -124, 429, 668, -124, 803, -124, 614, 599, -124,
+ -124, -124, 513, 514, 879, -124, -124, 595, 738, 677,
+ -124, -124, 0, 0, 0, -124, 0, -124, -124, 0,
+ 490, 0, -124, -124, 0, 0, -124, 0, -124, -124,
+ -124, -124, 654, -124, -325, -325, -325, -325, -325, -325,
+ -325, 0, -325, -325, -325, -325, -325, 0, -325, -325,
+ -325, -325, -325, -325, -325, -325, -325, -325, -325, -325,
+ -325, -325, -325, 0, -325, -325, 0, 0, 0, 0,
+ 0, -325, 0, 0, -325, 0, -325, 0, 0, -325,
+ -325, -325, 0, 0, 0, -325, -325, 0, 0, 0,
+ -325, -325, 0, 0, 0, -325, 0, -325, -325, 0,
+ 0, 0, -325, -325, 0, 0, -325, 0, -325, 0,
+ -325, -325, 331, -325, -325, -325, 0, 0, 0, -325,
+ -325, 0, -325, 0, 0, 0, -325, 0, -325, -325,
+ -325, -325, -325, -325, -325, -325, -325, -325, -325, 0,
+ -325, 0, -325, 0, -325, -325, 0, 0, 0, 0,
+ 0, -325, 273, 274, -325, 275, 276, 277, 278, -325,
+ -325, -325, 0, 0, 0, -325, -325, 0, 0, 0,
+ -325, -325, 0, 0, 0, -325, 0, -325, -325, 0,
+ 0, 0, -325, -325, 0, 0, -325, 0, -325, -300,
+ -325, -325, 838, -325, -325, -325, 0, 0, 0, -325,
+ -325, 0, -325, 0, 0, 0, -325, 0, -325, -325,
+ -325, -325, -325, -325, -325, -325, -325, -325, -325, 0,
+ -325, 0, -325, 0, -325, -325, 0, 0, 0, 0,
+ 0, -325, 0, 0, -325, 0, 0, 0, 0, -325,
+ -325, -325, 0, 0, 0, -325, -325, 0, 0, 0,
+ -325, -325, 0, 0, 0, -325, 0, -325, -325, 0,
+ 0, 0, -325, -325, 0, 0, -325, 0, -325, 0,
+ -325, -325, 867, -325, -335, -335, 0, 0, 0, -335,
+ -335, 0, -335, 0, 0, 0, -335, 0, -335, -335,
+ -335, -335, -335, -335, -335, -335, -335, -335, -335, 0,
+ -335, 0, -335, 0, -335, -335, 0, 0, 0, 75,
+ 202, -335, 0, 0, -335, 0, 0, 0, 0, -335,
+ -335, -335, 0, 0, 0, -335, -335, 0, 0, 0,
+ -335, -335, 0, 0, 0, -335, 14, -335, -335, 0,
+ 0, 0, -335, -335, 694, 0, -335, 0, -335, 0,
+ -335, -335, 663, -335, 664, 51, 203, 0, 0, 103,
+ 104, 0, 105, 0, 0, 204, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 205, 0,
+ 106, 0, 15, 0, 107, 108, 0, 0, 0, 0,
+ 0, 109, 0, 0, 110, 0, 0, 0, 0, 111,
+ 112, 113, 0, 0, 0, 114, 115, 0, 0, 665,
+ 116, 117, 0, 0, 0, 118, 0, 119, 52, 0,
+ 0, 0, 120, 53, 0, 0, 121, 0, 0, -203,
+ 122, 123, 663, 666, 664, 51, 0, 0, 0, 103,
+ 104, 258, 105, 259, 260, 261, 262, 263, 264, 265,
+ 266, 267, 268, 269, 270, 271, 272, 0, 0, 0,
+ 106, 0, 15, 0, 107, 108, 0, 0, 0, 0,
+ 0, 109, 0, 0, 110, 0, 0, 0, 0, 111,
+ 112, 113, 0, 0, 0, 114, 115, 0, 0, 665,
+ 116, 117, 0, 0, 0, 118, 0, 119, 52, 0,
+ 0, 0, 120, 53, 0, 0, 121, 0, 0, -258,
+ 122, 123, 663, 666, 664, 51, 0, 0, 0, 103,
+ 104, 0, 105, 228, 0, 0, 5, 0, 7, 140,
+ 0, 0, 0, 0, 9, 10, 11, 0, 0, 0,
+ 106, 0, 15, 0, 107, 108, 0, 0, 0, 0,
+ 13, 109, 0, 15, 110, 0, 0, 0, 0, 111,
+ 112, 113, 0, 0, 0, 114, 115, 16, 0, 665,
+ 116, 117, 0, 0, 0, 118, 0, 119, 52, 0,
+ 0, 0, 120, 53, 0, 0, 121, 0, 0, 22,
+ 122, 123, 196, 666, 24, -28, -28, -28, -28, 229,
+ -261, 0, 0, -28, -28, -28, 0, 0, 0, 0,
+ 0, 350, 0, 0, -24, -24, -24, -24, 197, -28,
+ 0, -175, -24, -24, -24, 0, 0, -175, 266, 267,
+ 268, 269, 270, 271, 272, 0, -28, 197, -24, 0,
+ -175, 0, 0, 0, 0, 0, -175, 0, 0, 0,
+ 198, 199, 0, 0, 0, -24, 0, 0, -28, 0,
+ 0, 0, 0, -28, 0, 0, 0, 0, -175, 198,
+ 199, 0, -175, -28, 0, 0, 0, -24, 0, 0,
+ 0, 0, -24, 0, 0, 0, 0, -175, 0, 0,
+ 344, -175, -24, -20, -20, -20, -20, 0, 0, 0,
+ 0, -20, -20, -20, 0, 0, 0, 0, 0, 331,
+ 0, 0, -488, -488, -488, -488, 197, -20, 0, -175,
+ -488, -488, -488, 0, 0, -175, 0, 0, 0, 0,
+ 0, 0, 0, 0, -20, 0, -488, 102, -488, 0,
+ 0, 0, 103, 104, 0, 105, 0, 0, 0, 0,
+ 0, 0, 0, -488, 0, 0, -20, 0, 0, 0,
+ 0, -20, 0, 106, 0, 15, -175, 107, 108, 0,
+ -175, -20, 0, 0, 109, -488, 0, 110, 0, 0,
+ -488, 0, 111, 112, 113, 0, 0, 0, 114, 115,
+ -488, 0, 0, 116, 117, 0, 102, 0, 118, 0,
+ 119, 103, 104, 0, 105, 120, 0, 0, 0, 121,
+ 0, 0, 0, 122, 123, 0, 0, 329, 0, 0,
+ 0, 0, 106, 0, 15, 0, 107, 108, 0, 0,
+ 0, 0, 0, 109, 0, 0, 110, 0, 0, 0,
+ 0, 111, 112, 113, 0, 0, 0, 114, 115, 0,
+ 0, 0, 116, 117, 0, 102, 0, 118, 0, 119,
+ 103, 104, 0, 105, 120, 0, 0, 0, 121, 0,
+ 0, 0, 122, 123, 0, 0, 412, 0, 0, 0,
+ 0, 106, 0, 15, 0, 107, 108, 0, 0, 0,
+ 0, 0, 109, 0, 0, 110, 0, 0, 0, 0,
+ 111, 112, 113, 0, 0, 0, 114, 115, 0, 0,
+ 0, 116, 117, 0, 102, 0, 118, 0, 119, 103,
+ 104, 0, 105, 120, 0, 0, 0, 121, 0, 0,
+ 0, 122, 123, 0, 0, 467, 0, 0, 0, 0,
+ 106, 0, 15, 0, 107, 108, 0, 0, 0, 0,
+ 0, 109, 0, 0, 110, 0, 0, 0, 0, 111,
+ 112, 113, 0, 0, 0, 114, 115, 0, 0, 0,
+ 116, 117, 0, 102, 0, 118, 0, 119, 103, 104,
+ 0, 105, 120, 0, 0, 0, 121, 0, 0, 0,
+ 122, 123, 0, 0, 506, 0, 0, 0, 0, 106,
+ 0, 15, 0, 107, 108, 0, 0, 0, 0, 0,
+ 109, 0, 0, 110, 0, 0, 0, 0, 111, 112,
+ 113, 0, 0, 0, 114, 115, 0, 0, 0, 116,
+ 117, 0, 0, 0, 118, 0, 119, 0, 0, 0,
+ 0, 120, 0, 0, 0, 121, 0, 0, 0, 122,
+ 123, 0, 0, 758, 664, 768, 6, 7, 8, 103,
+ 104, 0, 105, 9, 10, 11, 769, 0, 770, 771,
+ 772, 773, 774, 775, 776, 777, 778, 779, 780, 13,
+ 106, 14, 15, 0, 107, 108, 0, 0, 0, 0,
+ 0, 109, 0, 0, 110, 0, 16, 0, 0, 111,
+ 112, 113, 0, 0, 0, 114, 115, 0, 0, 0,
+ 116, 117, 0, 0, 0, 118, 0, 119, 781, 0,
+ 0, 0, 120, 782, 0, 0, 121, 0, 783, 0,
+ 122, 123, 0, 367, 664, 51, 0, 0, 0, 103,
+ 104, 0, 105, 0, 0, 0, 769, 0, 770, 771,
+ 772, 773, 774, 775, 776, 777, 778, 779, 780, 0,
+ 106, 0, 15, 0, 107, 108, 0, 0, 0, 0,
+ 0, 109, 0, 0, 110, 0, 0, 0, 0, 111,
+ 112, 113, 0, 0, 0, 114, 115, 0, 102, 0,
+ 116, 117, 0, 103, 104, 118, 105, 119, 52, 0,
+ 0, 0, 120, 53, 0, 0, 121, 0, 783, 0,
+ 122, 123, 0, 367, 106, 0, 15, 0, 107, 108,
+ 0, 0, 0, 0, 0, 109, 0, 0, 110, 0,
+ 0, 0, 0, 111, 112, 113, 0, 0, 0, 114,
+ 115, 0, 0, 0, 116, 117, 0, 0, 0, 118,
+ 0, 119, 0, 0, 0, 0, 120, 0, 0, 0,
+ 121, 0, 0, 0, 122, 123, 0, 484, 149, 150,
+ 0, 151, 152, 0, 0, 0, 153, 154, 155, 156,
+ 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
+ 167, 168, 169, 170, 171, 0, 102, 5, 6, 7,
+ 8, 103, 104, 172, 105, 9, 10, 11, 5, 6,
+ 7, 8, 0, 0, 0, 0, 9, 10, 11, 0,
+ 0, 13, 106, 14, 15, 0, 107, 108, 0, 0,
+ 0, 0, 13, 109, 14, 0, 110, 174, 16, 0,
+ 0, 111, 112, 113, 0, 0, 305, 114, 115, 16,
+ 0, 0, 116, 117, 0, 0, 0, 118, 0, 119,
+ 22, 0, 0, 0, 120, 24, 0, 0, 121, 0,
+ 0, 22, 122, 123, 102, 5, 24, 7, 140, 103,
+ 104, 84, 105, 9, 10, 11, 260, 261, 262, 263,
+ 264, 265, 266, 267, 268, 269, 270, 271, 272, 13,
+ 106, 0, 15, 0, 107, 108, 0, 0, 0, 0,
+ 0, 109, 0, 0, 110, 0, 16, 0, 0, 111,
+ 112, 113, 0, 0, 0, 114, 115, 0, 102, 0,
+ 116, 117, 0, 103, 104, 118, 105, 119, 22, 0,
+ 0, 0, 120, 24, 0, 0, 121, 0, 0, 0,
+ 122, 123, 0, 0, 106, 0, 15, 0, 107, 108,
+ 0, 0, 0, 0, 0, 109, 0, 0, 110, 0,
+ 0, 0, 0, 111, 112, 113, 0, 0, 0, 114,
+ 115, 0, 102, 0, 116, 117, 0, 103, 104, 118,
+ 105, 119, 371, 0, 0, 0, 120, 0, 0, 0,
+ 121, 0, 0, 0, 122, 123, 0, 0, 106, 0,
+ 15, 0, 107, 108, 0, 0, 0, 0, 0, 109,
+ 0, 0, 110, 0, 0, 0, 0, 111, 112, 113,
+ 0, 0, 0, 114, 115, 0, 102, 0, 116, 117,
+ 0, 103, 104, 118, 105, 119, 0, 0, 0, 0,
+ 120, 0, 0, 0, 121, 0, 825, 0, 122, 123,
+ 0, 0, 106, 0, 15, 0, 107, 108, 0, 0,
+ 0, 0, 0, 109, 0, 0, 110, 0, 0, 0,
+ 0, 111, 112, 113, 0, 0, 0, 114, 115, 0,
+ 102, 0, 116, 117, 0, 103, 104, 118, 105, 119,
+ 0, 0, 0, 0, 120, 0, 0, 0, 121, 0,
+ 0, 0, 122, 123, 0, 0, 106, 0, 15, 0,
+ 107, 108, 0, 0, 0, 0, 0, 109, 0, 0,
+ 110, 0, 0, 0, 0, 111, 112, 113, 0, 0,
+ 0, 114, 115, 0, 102, 0, 252, 117, 0, 103,
+ 104, 118, 105, 119, 0, 0, 0, 0, 120, 0,
+ 0, 0, 121, 0, 0, 0, 122, 123, 0, 0,
+ 106, 0, 15, 0, 107, 108, 0, 0, 0, 0,
+ 0, 109, 0, 0, 110, 0, 0, 0, 0, 111,
+ 112, 113, 0, 0, 0, 114, 115, 0, 510, 0,
+ 254, 117, 0, 103, 104, 118, 105, 119, 0, 0,
+ 0, 0, 120, 0, 0, 0, 121, 0, 0, 0,
+ 122, 123, 0, 0, 106, 0, 15, 0, 107, 108,
+ 0, 0, 0, 0, 0, 109, 0, 0, 110, 0,
+ 0, 0, 0, 111, 112, 113, 0, 0, 0, 114,
+ 115, 0, 0, 0, 116, 117, 0, 0, 0, 118,
+ 0, 119, 0, 0, 0, 0, 120, 0, 0, 0,
+ 121, 0, 0, 545, 122, 123, 5, 0, 7, 140,
+ 0, 0, 0, 0, 9, 10, 11, 0, 0, 0,
+ 0, 545, 0, 0, 5, 0, 7, 140, 0, 0,
+ 13, 0, 9, 10, 11, 262, 263, 264, 265, 266,
+ 267, 268, 269, 270, 271, 272, 0, 16, 13, 0,
+ 0, 0, 0, 0, 0, 4, 0, -128, 5, 6,
+ 7, 8, 0, 0, 0, 16, 9, 10, 11, 22,
+ -440, -440, -440, 0, 24, 0, 0, 0, 0, 546,
+ -440, 12, 13, 0, 14, 15, 0, 22, -439, -439,
+ -439, 0, 24, 0, 0, 0, 0, 546, -439, 16,
+ 0, 0, 17, 18, -128, 0, 0, 0, 0, 0,
+ 0, 0, 0, -128, 0, 19, 20, 21, 0, 0,
+ 0, 22, 0, 0, 0, 23, 24, 25, 26, 0,
+ 4, 27, -128, 5, 6, 7, 8, 0, 0, 0,
+ 0, 9, 10, 11, 263, 264, 265, 266, 267, 268,
+ 269, 270, 271, 272, 0, 0, 0, 13, 4, 14,
+ -128, 5, 6, 7, 8, 0, 0, 0, 0, 9,
+ 10, 11, 0, 0, 16, 0, 0, 531, 532, -128,
+ 0, 0, 0, 0, 0, 13, 0, 14, -128, 0,
+ 0, 0, 0, 0, 0, 0, 22, 0, 0, 0,
+ 0, 24, 16, 0, 0, 0, 27, -128, 441, 0,
+ 442, 5, 6, 7, 8, 0, -128, 443, 0, 9,
+ 10, 11, 0, 0, 22, 0, 0, 441, 0, 24,
+ 5, 6, 7, 8, 27, 13, 443, 14, 9, 10,
+ 11, 5, 0, 7, 290, 0, 0, 0, 0, 9,
+ 10, 11, 16, 0, 13, 0, 14, 0, 0, 0,
+ 5, 6, 7, 8, 0, 13, 0, 0, 9, 10,
+ 11, 16, 0, 0, 22, 0, 0, 0, 0, 24,
+ 0, 0, 16, -385, 13, 0, 14, 0, 0, 0,
+ 0, 0, 0, 22, 0, 0, 0, 0, 24, 0,
+ 0, 16, -385, 0, 22, 0, 0, 0, 0, 24,
+ 5, 6, 7, 8, -270, -270, 0, 0, 9, 10,
+ 11, 0, 0, 22, 0, 0, 0, 0, 24, 0,
+ 0, 0, 0, 598, 13, 0, 14, 0, 0, 0,
+ 0, 0, 0, 0, 149, 150, 0, 151, 152, 0,
+ 0, 16, 153, 154, 155, 156, 157, 158, 159, 160,
+ 161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
+ 171, 0, 0, 22, 0, 14, 0, 0, 24, 172,
+ 256, 257, 258, 835, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 0, 0,
+ 173, 0, 0, 0, 0, 0, 149, 150, 0, 151,
+ 152, 0, 0, 174, 153, 154, 155, 156, 157, 158,
+ 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,
+ 169, 170, 171, 0, 149, 150, 0, 151, 152, 0,
+ 0, 374, 153, 154, 155, 156, 157, 158, 159, 160,
+ 161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
+ 171, 0, 0, 0, 0, 0, 0, 0, 0, 172,
+ 149, 150, 0, 151, 152, 174, 0, 0, 153, 154,
+ 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
+ 165, 166, 167, 168, 169, 170, 171, 0, 0, 5,
+ 0, 7, 290, 174, 0, 583, 0, 9, 10, 11,
+ 5, 6, 7, 8, 0, 0, 443, 0, 9, 10,
+ 11, 0, 0, 13, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 13, 0, 14, 0, 0, 174,
+ 16, 0, 0, 0, 0, 283, 0, 0, 0, 0,
+ 0, 16, 0, 0, 284, 285, 0, 0, 0, 0,
+ 0, 0, 22, 0, 0, 0, 0, 24, 0, 0,
+ 0, 0, 0, 22, 5, 6, 7, 8, 24, 0,
+ 631, 0, 9, 10, 11, 5, 6, 7, 8, 0,
+ 0, 0, 0, 9, 10, 11, 0, 0, 13, 0,
+ 14, 0, 0, 0, 5, 6, 7, 8, 0, 13,
+ 0, 14, 9, 10, 11, 16, 0, 0, 0, 0,
+ 0, 0, 5, 0, 7, 140, 16, 0, 13, 0,
+ 9, 10, 11, 0, 0, 0, 0, 22, 0, 0,
+ 0, 5, 24, 7, 290, 16, 13, 0, 22, 9,
+ 10, 11, 0, 24, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 16, 0, 13, 0, 22, 0, 0,
+ 0, 0, 24, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 16, 0, 0, 22, 855, 0, 0, 0,
+ 24, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 22, 0, 0, 0, 0, 24,
+ 0, 256, 257, 258, 856, 259, 260, 261, 262, 263,
+ 264, 265, 266, 267, 268, 269, 270, 271, 272, 256,
+ 257, 258, 894, 259, 260, 261, 262, 263, 264, 265,
+ 266, 267, 268, 269, 270, 271, 272, 256, 257, 258,
+ 0, 259, 260, 261, 262, 263, 264, 265, 266, 267,
+ 268, 269, 270, 271, 272
+};
+
+static const short yycheck[] = { 9,
+ 10, 11, 209, 24, 2, 3, 16, 60, 61, 19,
+ 20, 288, 208, 23, 83, 25, 26, 2, 3, 2,
+ 3, 33, 2, 3, 91, 22, 85, 24, 177, 36,
+ 326, 318, 345, 31, 203, 33, 98, 243, 351, 347,
+ 66, 39, 98, 33, 31, 277, 67, 333, 32, 33,
+ 71, 411, 107, 108, 39, 177, 39, 284, 113, 39,
+ 636, 477, 142, 553, 74, 145, 434, 432, 204, 124,
+ 67, 61, 1, 80, 71, 194, 58, 200, 736, 77,
+ 135, 88, 1, 818, 94, 83, 1, 85, 116, 38,
+ 77, 10, 9, 91, 1, 3, 3, 4, 85, 109,
+ 3, 4, 27, 1, 76, 45, 38, 521, 98, 81,
+ 715, 525, 59, 60, 283, 98, 38, 324, 38, 0,
+ 3, 4, 30, 45, 246, 45, 116, 76, 733, 76,
+ 0, 3, 4, 868, 59, 60, 146, 423, 148, 59,
+ 417, 81, 50, 801, 76, 173, 199, 214, 77, 3,
+ 4, 59, 60, 888, 568, 145, 891, 571, 893, 76,
+ 67, 59, 172, 82, 67, 72, 901, 82, 59, 72,
+ 38, 233, 182, 183, 539, 185, 186, 233, 38, 82,
+ 59, 408, 38, 173, 67, 45, 844, 59, 420, 72,
+ 59, 59, 245, 191, 3, 67, 194, 195, 933, 82,
+ 72, 208, 45, 339, 191, 59, 204, 343, 195, 699,
+ 700, 334, 219, 67, 82, 225, 214, 204, 72, 247,
+ 76, 288, 345, 342, 252, 278, 254, 77, 351, 77,
+ 39, 81, 285, 892, 520, 358, 3, 360, 248, 604,
+ 527, 30, 232, 233, 660, 613, 230, 30, 232, 38,
+ 233, 76, 234, 82, 236, 377, 81, 247, 834, 3,
+ 4, 920, 252, 30, 254, 275, 276, 30, 3, 4,
+ 630, 3, 4, 301, 65, 7, 1, 59, 60, 4,
+ 5, 6, 7, 50, 82, 10, 76, 12, 13, 14,
+ 311, 81, 59, 579, 76, 348, 59, 60, 30, 309,
+ 59, 60, 82, 28, 3, 4, 5, 6, 7, 48,
+ 49, 301, 59, 729, 311, 370, 50, 76, 50, 606,
+ 45, 59, 812, 67, 63, 59, 60, 59, 72, 77,
+ 328, 338, 67, 81, 387, 77, 59, 72, 82, 81,
+ 72, 339, 67, 353, 342, 343, 27, 72, 76, 30,
+ 417, 583, 339, 81, 560, 36, 343, 82, 27, 30,
+ 592, 30, 415, 640, 486, 514, 78, 36, 67, 655,
+ 3, 4, 658, 72, 1, 78, 438, 4, 76, 6,
+ 7, 59, 438, 81, 59, 12, 13, 14, 59, 60,
+ 59, 60, 514, 701, 77, 622, 77, 30, 81, 427,
+ 81, 28, 689, 77, 31, 38, 76, 81, 77, 419,
+ 431, 9, 81, 411, 68, 69, 70, 50, 45, 68,
+ 69, 70, 227, 839, 78, 423, 59, 623, 426, 78,
+ 235, 3, 4, 445, 431, 712, 434, 427, 423, 72,
+ 67, 81, 674, 423, 75, 72, 458, 445, 438, 434,
+ 434, 574, 621, 77, 434, 445, 579, 81, 627, 77,
+ 444, 445, 7, 81, 586, 77, 3, 4, 458, 81,
+ 251, 76, 699, 553, 554, 256, 257, 76, 50, 706,
+ 261, 262, 263, 264, 265, 266, 267, 268, 269, 270,
+ 271, 272, 77, 30, 38, 67, 81, 68, 69, 70,
+ 72, 5, 512, 7, 516, 50, 575, 78, 77, 68,
+ 69, 70, 81, 50, 59, 60, 77, 804, 516, 78,
+ 81, 519, 59, 60, 536, 731, 516, 50, 51, 52,
+ 82, 515, 59, 656, 519, 658, 534, 77, 536, 519,
+ 36, 346, 3, 4, 77, 78, 536, 534, 617, 618,
+ 81, 535, 536, 612, 616, 553, 554, 67, 548, 557,
+ 616, 767, 77, 547, 548, 76, 553, 554, 578, 30,
+ 883, 352, 885, 640, 76, 565, 82, 575, 76, 638,
+ 564, 565, 608, 609, 59, 60, 755, 59, 60, 50,
+ 3, 4, 602, 77, 7, 38, 3, 59, 59, 597,
+ 7, 77, 78, 3, 4, 59, 60, 7, 389, 390,
+ 597, 72, 76, 611, 612, 613, 623, 30, 77, 617,
+ 618, 77, 78, 30, 622, 612, 616, 10, 613, 613,
+ 30, 927, 630, 613, 76, 622, 63, 50, 636, 935,
+ 638, 59, 60, 50, 3, 712, 59, 60, 7, 702,
+ 50, 638, 59, 60, 82, 665, 863, 128, 129, 59,
+ 76, 27, 9, 869, 83, 77, 36, 472, 78, 78,
+ 76, 30, 76, 78, 479, 480, 78, 38, 731, 3,
+ 4, 76, 76, 1, 753, 76, 4, 5, 6, 7,
+ 76, 50, 76, 38, 12, 13, 14, 76, 83, 76,
+ 59, 699, 700, 83, 910, 911, 30, 76, 706, 82,
+ 28, 721, 699, 700, 767, 496, 6, 7, 76, 706,
+ 63, 731, 12, 13, 14, 778, 50, 45, 63, 4,
+ 5, 6, 7, 731, 76, 59, 36, 12, 13, 14,
+ 78, 81, 83, 798, 32, 38, 731, 745, 731, 67,
+ 83, 731, 77, 28, 72, 753, 76, 767, 745, 81,
+ 883, 782, 885, 816, 82, 834, 819, 820, 573, 779,
+ 45, 5, 6, 7, 827, 76, 788, 836, 12, 13,
+ 14, 77, 3, 77, 781, 782, 567, 38, 83, 842,
+ 788, 63, 67, 78, 78, 38, 849, 72, 788, 38,
+ 798, 582, 77, 787, 788, 54, 55, 860, 57, 58,
+ 59, 60, 78, 798, 812, 798, 869, 81, 798, 624,
+ 625, 626, 63, 628, 629, 812, 38, 76, 45, 46,
+ 47, 48, 49, 50, 51, 52, 834, 81, 836, 892,
+ 1, 78, 3, 36, 63, 83, 651, 8, 9, 836,
+ 11, 1, 78, 38, 4, 5, 6, 7, 59, 869,
+ 59, 914, 12, 13, 14, 646, 38, 920, 29, 650,
+ 31, 59, 33, 34, 77, 680, 681, 682, 28, 40,
+ 30, 77, 43, 5, 6, 7, 38, 48, 49, 50,
+ 12, 13, 14, 54, 55, 45, 7, 678, 59, 60,
+ 77, 77, 16, 64, 78, 66, 59, 77, 30, 77,
+ 71, 59, 717, 694, 75, 17, 63, 67, 79, 80,
+ 76, 82, 72, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 82, 1, 715, 3, 4, 718, 6, 7,
+ 8, 9, 77, 11, 12, 13, 14, 48, 49, 50,
+ 51, 52, 733, 76, 9, 736, 59, 77, 76, 764,
+ 28, 29, 77, 31, 76, 33, 34, 77, 77, 0,
+ 77, 752, 40, 81, 0, 43, 76, 45, 76, 420,
+ 48, 49, 50, 77, 77, 819, 54, 55, 334, 656,
+ 798, 59, 60, 774, 639, 87, 64, 419, 66, 67,
+ 291, 355, 646, 71, 72, 233, 574, 75, 360, 225,
+ 656, 79, 80, 580, 82, 658, 353, 869, 869, 915,
+ 801, 414, 1, 917, 3, 4, 5, 6, 7, 8,
+ 9, 557, 11, 12, 13, 14, 15, 426, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 25, 33, 34, 544, 753, 426, 750,
+ 618, 40, 310, 844, 43, 745, 45, 537, 519, 48,
+ 49, 50, 422, 422, 855, 54, 55, 514, 674, 586,
+ 59, 60, -1, -1, -1, 64, -1, 66, 67, -1,
+ 377, -1, 71, 72, -1, -1, 75, -1, 77, 78,
+ 79, 80, 1, 82, 3, 4, 5, 6, 7, 8,
+ 9, -1, 11, 12, 13, 14, 15, -1, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, -1, 33, 34, -1, -1, -1, -1,
+ -1, 40, -1, -1, 43, -1, 45, -1, -1, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, -1, -1,
+ 59, 60, -1, -1, -1, 64, -1, 66, 67, -1,
+ -1, -1, 71, 72, -1, -1, 75, -1, 77, -1,
+ 79, 80, 1, 82, 3, 4, -1, -1, -1, 8,
+ 9, -1, 11, -1, -1, -1, 15, -1, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, -1,
+ 29, -1, 31, -1, 33, 34, -1, -1, -1, -1,
+ -1, 40, 54, 55, 43, 57, 58, 59, 60, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, -1, -1,
+ 59, 60, -1, -1, -1, 64, -1, 66, 67, -1,
+ -1, -1, 71, 72, -1, -1, 75, -1, 77, 78,
+ 79, 80, 1, 82, 3, 4, -1, -1, -1, 8,
+ 9, -1, 11, -1, -1, -1, 15, -1, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, -1,
+ 29, -1, 31, -1, 33, 34, -1, -1, -1, -1,
+ -1, 40, -1, -1, 43, -1, -1, -1, -1, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, -1, -1,
+ 59, 60, -1, -1, -1, 64, -1, 66, 67, -1,
+ -1, -1, 71, 72, -1, -1, 75, -1, 77, -1,
+ 79, 80, 1, 82, 3, 4, -1, -1, -1, 8,
+ 9, -1, 11, -1, -1, -1, 15, -1, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, -1,
+ 29, -1, 31, -1, 33, 34, -1, -1, -1, 3,
+ 4, 40, -1, -1, 43, -1, -1, -1, -1, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, -1, -1,
+ 59, 60, -1, -1, -1, 64, 30, 66, 67, -1,
+ -1, -1, 71, 72, 38, -1, 75, -1, 77, -1,
+ 79, 80, 1, 82, 3, 4, 50, -1, -1, 8,
+ 9, -1, 11, -1, -1, 59, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 72, -1,
+ 29, -1, 31, -1, 33, 34, -1, -1, -1, -1,
+ -1, 40, -1, -1, 43, -1, -1, -1, -1, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, -1, 58,
+ 59, 60, -1, -1, -1, 64, -1, 66, 67, -1,
+ -1, -1, 71, 72, -1, -1, 75, -1, -1, 78,
+ 79, 80, 1, 82, 3, 4, -1, -1, -1, 8,
+ 9, 37, 11, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, -1, -1, -1,
+ 29, -1, 31, -1, 33, 34, -1, -1, -1, -1,
+ -1, 40, -1, -1, 43, -1, -1, -1, -1, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, -1, 58,
+ 59, 60, -1, -1, -1, 64, -1, 66, 67, -1,
+ -1, -1, 71, 72, -1, -1, 75, -1, -1, 78,
+ 79, 80, 1, 82, 3, 4, -1, -1, -1, 8,
+ 9, -1, 11, 1, -1, -1, 4, -1, 6, 7,
+ -1, -1, -1, -1, 12, 13, 14, -1, -1, -1,
+ 29, -1, 31, -1, 33, 34, -1, -1, -1, -1,
+ 28, 40, -1, 31, 43, -1, -1, -1, -1, 48,
+ 49, 50, -1, -1, -1, 54, 55, 45, -1, 58,
+ 59, 60, -1, -1, -1, 64, -1, 66, 67, -1,
+ -1, -1, 71, 72, -1, -1, 75, -1, -1, 67,
+ 79, 80, 1, 82, 72, 4, 5, 6, 7, 77,
+ 78, -1, -1, 12, 13, 14, -1, -1, -1, -1,
+ -1, 1, -1, -1, 4, 5, 6, 7, 27, 28,
+ -1, 30, 12, 13, 14, -1, -1, 36, 46, 47,
+ 48, 49, 50, 51, 52, -1, 45, 27, 28, -1,
+ 30, -1, -1, -1, -1, -1, 36, -1, -1, -1,
+ 59, 60, -1, -1, -1, 45, -1, -1, 67, -1,
+ -1, -1, -1, 72, -1, -1, -1, -1, 77, 59,
+ 60, -1, 81, 82, -1, -1, -1, 67, -1, -1,
+ -1, -1, 72, -1, -1, -1, -1, 77, -1, -1,
+ 1, 81, 82, 4, 5, 6, 7, -1, -1, -1,
+ -1, 12, 13, 14, -1, -1, -1, -1, -1, 1,
+ -1, -1, 4, 5, 6, 7, 27, 28, -1, 30,
+ 12, 13, 14, -1, -1, 36, -1, -1, -1, -1,
+ -1, -1, -1, -1, 45, -1, 28, 3, 30, -1,
+ -1, -1, 8, 9, -1, 11, -1, -1, -1, -1,
+ -1, -1, -1, 45, -1, -1, 67, -1, -1, -1,
+ -1, 72, -1, 29, -1, 31, 77, 33, 34, -1,
+ 81, 82, -1, -1, 40, 67, -1, 43, -1, -1,
+ 72, -1, 48, 49, 50, -1, -1, -1, 54, 55,
+ 82, -1, -1, 59, 60, -1, 3, -1, 64, -1,
+ 66, 8, 9, -1, 11, 71, -1, -1, -1, 75,
+ -1, -1, -1, 79, 80, -1, -1, 83, -1, -1,
+ -1, -1, 29, -1, 31, -1, 33, 34, -1, -1,
+ -1, -1, -1, 40, -1, -1, 43, -1, -1, -1,
+ -1, 48, 49, 50, -1, -1, -1, 54, 55, -1,
+ -1, -1, 59, 60, -1, 3, -1, 64, -1, 66,
+ 8, 9, -1, 11, 71, -1, -1, -1, 75, -1,
+ -1, -1, 79, 80, -1, -1, 83, -1, -1, -1,
+ -1, 29, -1, 31, -1, 33, 34, -1, -1, -1,
+ -1, -1, 40, -1, -1, 43, -1, -1, -1, -1,
+ 48, 49, 50, -1, -1, -1, 54, 55, -1, -1,
+ -1, 59, 60, -1, 3, -1, 64, -1, 66, 8,
+ 9, -1, 11, 71, -1, -1, -1, 75, -1, -1,
+ -1, 79, 80, -1, -1, 83, -1, -1, -1, -1,
+ 29, -1, 31, -1, 33, 34, -1, -1, -1, -1,
+ -1, 40, -1, -1, 43, -1, -1, -1, -1, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, -1, -1,
+ 59, 60, -1, 3, -1, 64, -1, 66, 8, 9,
+ -1, 11, 71, -1, -1, -1, 75, -1, -1, -1,
+ 79, 80, -1, -1, 83, -1, -1, -1, -1, 29,
+ -1, 31, -1, 33, 34, -1, -1, -1, -1, -1,
+ 40, -1, -1, 43, -1, -1, -1, -1, 48, 49,
+ 50, -1, -1, -1, 54, 55, -1, -1, -1, 59,
+ 60, -1, -1, -1, 64, -1, 66, -1, -1, -1,
+ -1, 71, -1, -1, -1, 75, -1, -1, -1, 79,
+ 80, -1, -1, 83, 3, 4, 5, 6, 7, 8,
+ 9, -1, 11, 12, 13, 14, 15, -1, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, -1, 33, 34, -1, -1, -1, -1,
+ -1, 40, -1, -1, 43, -1, 45, -1, -1, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, -1, -1,
+ 59, 60, -1, -1, -1, 64, -1, 66, 67, -1,
+ -1, -1, 71, 72, -1, -1, 75, -1, 77, -1,
+ 79, 80, -1, 82, 3, 4, -1, -1, -1, 8,
+ 9, -1, 11, -1, -1, -1, 15, -1, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, -1,
+ 29, -1, 31, -1, 33, 34, -1, -1, -1, -1,
+ -1, 40, -1, -1, 43, -1, -1, -1, -1, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, 3, -1,
+ 59, 60, -1, 8, 9, 64, 11, 66, 67, -1,
+ -1, -1, 71, 72, -1, -1, 75, -1, 77, -1,
+ 79, 80, -1, 82, 29, -1, 31, -1, 33, 34,
+ -1, -1, -1, -1, -1, 40, -1, -1, 43, -1,
+ -1, -1, -1, 48, 49, 50, -1, -1, -1, 54,
+ 55, -1, -1, -1, 59, 60, -1, -1, -1, 64,
+ -1, 66, -1, -1, -1, -1, 71, -1, -1, -1,
+ 75, -1, -1, -1, 79, 80, -1, 82, 3, 4,
+ -1, 6, 7, -1, -1, -1, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, -1, 3, 4, 5, 6,
+ 7, 8, 9, 38, 11, 12, 13, 14, 4, 5,
+ 6, 7, -1, -1, -1, -1, 12, 13, 14, -1,
+ -1, 28, 29, 30, 31, -1, 33, 34, -1, -1,
+ -1, -1, 28, 40, 30, -1, 43, 72, 45, -1,
+ -1, 48, 49, 50, -1, -1, 81, 54, 55, 45,
+ -1, -1, 59, 60, -1, -1, -1, 64, -1, 66,
+ 67, -1, -1, -1, 71, 72, -1, -1, 75, -1,
+ -1, 67, 79, 80, 3, 4, 72, 6, 7, 8,
+ 9, 77, 11, 12, 13, 14, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 28,
+ 29, -1, 31, -1, 33, 34, -1, -1, -1, -1,
+ -1, 40, -1, -1, 43, -1, 45, -1, -1, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, 3, -1,
+ 59, 60, -1, 8, 9, 64, 11, 66, 67, -1,
+ -1, -1, 71, 72, -1, -1, 75, -1, -1, -1,
+ 79, 80, -1, -1, 29, -1, 31, -1, 33, 34,
+ -1, -1, -1, -1, -1, 40, -1, -1, 43, -1,
+ -1, -1, -1, 48, 49, 50, -1, -1, -1, 54,
+ 55, -1, 3, -1, 59, 60, -1, 8, 9, 64,
+ 11, 66, 67, -1, -1, -1, 71, -1, -1, -1,
+ 75, -1, -1, -1, 79, 80, -1, -1, 29, -1,
+ 31, -1, 33, 34, -1, -1, -1, -1, -1, 40,
+ -1, -1, 43, -1, -1, -1, -1, 48, 49, 50,
+ -1, -1, -1, 54, 55, -1, 3, -1, 59, 60,
+ -1, 8, 9, 64, 11, 66, -1, -1, -1, -1,
+ 71, -1, -1, -1, 75, -1, 77, -1, 79, 80,
+ -1, -1, 29, -1, 31, -1, 33, 34, -1, -1,
+ -1, -1, -1, 40, -1, -1, 43, -1, -1, -1,
+ -1, 48, 49, 50, -1, -1, -1, 54, 55, -1,
+ 3, -1, 59, 60, -1, 8, 9, 64, 11, 66,
+ -1, -1, -1, -1, 71, -1, -1, -1, 75, -1,
+ -1, -1, 79, 80, -1, -1, 29, -1, 31, -1,
+ 33, 34, -1, -1, -1, -1, -1, 40, -1, -1,
+ 43, -1, -1, -1, -1, 48, 49, 50, -1, -1,
+ -1, 54, 55, -1, 3, -1, 59, 60, -1, 8,
+ 9, 64, 11, 66, -1, -1, -1, -1, 71, -1,
+ -1, -1, 75, -1, -1, -1, 79, 80, -1, -1,
+ 29, -1, 31, -1, 33, 34, -1, -1, -1, -1,
+ -1, 40, -1, -1, 43, -1, -1, -1, -1, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, 3, -1,
+ 59, 60, -1, 8, 9, 64, 11, 66, -1, -1,
+ -1, -1, 71, -1, -1, -1, 75, -1, -1, -1,
+ 79, 80, -1, -1, 29, -1, 31, -1, 33, 34,
+ -1, -1, -1, -1, -1, 40, -1, -1, 43, -1,
+ -1, -1, -1, 48, 49, 50, -1, -1, -1, 54,
+ 55, -1, -1, -1, 59, 60, -1, -1, -1, 64,
+ -1, 66, -1, -1, -1, -1, 71, -1, -1, -1,
+ 75, -1, -1, 1, 79, 80, 4, -1, 6, 7,
+ -1, -1, -1, -1, 12, 13, 14, -1, -1, -1,
+ -1, 1, -1, -1, 4, -1, 6, 7, -1, -1,
+ 28, -1, 12, 13, 14, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, -1, 45, 28, -1,
+ -1, -1, -1, -1, -1, 1, -1, 3, 4, 5,
+ 6, 7, -1, -1, -1, 45, 12, 13, 14, 67,
+ 68, 69, 70, -1, 72, -1, -1, -1, -1, 77,
+ 78, 27, 28, -1, 30, 31, -1, 67, 68, 69,
+ 70, -1, 72, -1, -1, -1, -1, 77, 78, 45,
+ -1, -1, 48, 49, 50, -1, -1, -1, -1, -1,
+ -1, -1, -1, 59, -1, 61, 62, 63, -1, -1,
+ -1, 67, -1, -1, -1, 71, 72, 73, 74, -1,
+ 1, 77, 3, 4, 5, 6, 7, -1, -1, -1,
+ -1, 12, 13, 14, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, -1, -1, -1, 28, 1, 30,
+ 3, 4, 5, 6, 7, -1, -1, -1, -1, 12,
+ 13, 14, -1, -1, 45, -1, -1, 48, 49, 50,
+ -1, -1, -1, -1, -1, 28, -1, 30, 59, -1,
+ -1, -1, -1, -1, -1, -1, 67, -1, -1, -1,
+ -1, 72, 45, -1, -1, -1, 77, 50, 1, -1,
+ 3, 4, 5, 6, 7, -1, 59, 10, -1, 12,
+ 13, 14, -1, -1, 67, -1, -1, 1, -1, 72,
+ 4, 5, 6, 7, 77, 28, 10, 30, 12, 13,
+ 14, 4, -1, 6, 7, -1, -1, -1, -1, 12,
+ 13, 14, 45, -1, 28, -1, 30, -1, -1, -1,
+ 4, 5, 6, 7, -1, 28, -1, -1, 12, 13,
+ 14, 45, -1, -1, 67, -1, -1, -1, -1, 72,
+ -1, -1, 45, 76, 28, -1, 30, -1, -1, -1,
+ -1, -1, -1, 67, -1, -1, -1, -1, 72, -1,
+ -1, 45, 76, -1, 67, -1, -1, -1, -1, 72,
+ 4, 5, 6, 7, 77, 78, -1, -1, 12, 13,
+ 14, -1, -1, 67, -1, -1, -1, -1, 72, -1,
+ -1, -1, -1, 77, 28, -1, 30, -1, -1, -1,
+ -1, -1, -1, -1, 3, 4, -1, 6, 7, -1,
+ -1, 45, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, -1, -1, 67, -1, 30, -1, -1, 72, 38,
+ 35, 36, 37, 77, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, -1, -1,
+ 59, -1, -1, -1, -1, -1, 3, 4, -1, 6,
+ 7, -1, -1, 72, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, -1, 3, 4, -1, 6, 7, -1,
+ -1, 38, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, -1, -1, -1, -1, -1, -1, -1, -1, 38,
+ 3, 4, -1, 6, 7, 72, -1, -1, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, -1, -1, 4,
+ -1, 6, 7, 72, -1, 38, -1, 12, 13, 14,
+ 4, 5, 6, 7, -1, -1, 10, -1, 12, 13,
+ 14, -1, -1, 28, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 28, -1, 30, -1, -1, 72,
+ 45, -1, -1, -1, -1, 50, -1, -1, -1, -1,
+ -1, 45, -1, -1, 59, 60, -1, -1, -1, -1,
+ -1, -1, 67, -1, -1, -1, -1, 72, -1, -1,
+ -1, -1, -1, 67, 4, 5, 6, 7, 72, -1,
+ 10, -1, 12, 13, 14, 4, 5, 6, 7, -1,
+ -1, -1, -1, 12, 13, 14, -1, -1, 28, -1,
+ 30, -1, -1, -1, 4, 5, 6, 7, -1, 28,
+ -1, 30, 12, 13, 14, 45, -1, -1, -1, -1,
+ -1, -1, 4, -1, 6, 7, 45, -1, 28, -1,
+ 12, 13, 14, -1, -1, -1, -1, 67, -1, -1,
+ -1, 4, 72, 6, 7, 45, 28, -1, 67, 12,
+ 13, 14, -1, 72, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 45, -1, 28, -1, 67, -1, -1,
+ -1, -1, 72, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 45, -1, -1, 67, 10, -1, -1, -1,
+ 72, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 67, -1, -1, -1, -1, 72,
+ -1, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 35, 36, 37,
+ -1, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52
+};
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+#line 3 "/usr/local/share/bison.simple"
+
+/* Skeleton output parser for bison,
+ Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+
+ 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+#ifndef alloca
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not GNU C. */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
+#include <alloca.h>
+#else /* not sparc */
+#if defined (MSDOS) && !defined (__TURBOC__)
+#include <malloc.h>
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+#include <malloc.h>
+ #pragma alloca
+#else /* not MSDOS, __TURBOC__, or _AIX */
+#ifdef __hpux
+#ifdef __cplusplus
+extern "C" {
+void *alloca (unsigned int);
+};
+#else /* not __cplusplus */
+void *alloca ();
+#endif /* not __cplusplus */
+#endif /* __hpux */
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc. */
+#endif /* not GNU C. */
+#endif /* alloca not defined. */
+
+/* This is the parser code that is written into each bison parser
+ when the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+/* Note: there must be only one dollar sign in this file.
+ It is replaced by the list of actions, each action
+ as one case of the switch. */
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT return(0)
+#define YYABORT return(1)
+#define YYERROR goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+ This remains here temporarily to ease the
+ transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+#define YYFAIL goto yyerrlab
+#define YYRECOVERING() (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { yychar = (token), yylval = (value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { yyerror ("syntax error: cannot back up"); YYERROR; } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+#ifndef YYPURE
+#define YYLEX yylex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#ifdef YYLEX_PARAM
+#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
+#else
+#define YYLEX yylex(&yylval, &yylloc)
+#endif
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX yylex(&yylval, YYLEX_PARAM)
+#else
+#define YYLEX yylex(&yylval)
+#endif
+#endif /* not YYLSP_NEEDED */
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int yychar; /* the lookahead symbol */
+YYSTYPE yylval; /* the semantic value of the */
+ /* lookahead symbol */
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc; /* location data for the lookahead */
+ /* symbol */
+#endif
+
+int yynerrs; /* number of parse errors so far */
+#endif /* not YYPURE */
+
+#if YYDEBUG != 0
+int yydebug; /* nonzero means print parse trace */
+/* Since this is uninitialized, it does not stop multiple parsers
+ from coexisting. */
+#endif
+
+/* YYINITDEPTH indicates the initial size of the parser's stacks */
+
+#ifndef YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH is the maximum size the stacks can grow to
+ (effective only if the built-in stack extension method is used). */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+int yyparse (void);
+#endif
+
+#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
+#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
+#else /* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_memcpy (from, to, count)
+ char *from;
+ char *to;
+ int count;
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_memcpy (char *from, char *to, int count)
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#endif
+#endif
+
+#line 192 "/usr/local/share/bison.simple"
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into yyparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#else
+#define YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#endif
+
+int
+yyparse(YYPARSE_PARAM)
+ YYPARSE_PARAM_DECL
+{
+ register int yystate;
+ register int yyn;
+ register short *yyssp;
+ register YYSTYPE *yyvsp;
+ int yyerrstatus; /* number of tokens to shift before error messages enabled */
+ int yychar1 = 0; /* lookahead token as an internal (translated) token number */
+
+ short yyssa[YYINITDEPTH]; /* the state stack */
+ YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
+
+ short *yyss = yyssa; /* refer to the stacks thru separate pointers */
+ YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+
+#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK (yyvsp--, yyssp--)
+#endif
+
+ int yystacksize = YYINITDEPTH;
+
+#ifdef YYPURE
+ int yychar;
+ YYSTYPE yylval;
+ int yynerrs;
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylloc;
+#endif
+#endif
+
+ YYSTYPE yyval; /* the variable used to return */
+ /* semantic values from the action */
+ /* routines */
+
+ int yylen;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Starting parse\n");
+#endif
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss - 1;
+ yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in yystate . */
+/* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks. */
+yynewstate:
+
+ *++yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Give user a chance to reallocate the stack */
+ /* Use copies of these so that the &'s don't force the real ones into memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+ YYLTYPE *yyls1 = yyls;
+#endif
+
+ /* Get the current used size of the three stacks, in elements. */
+ int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ /* Each stack pointer address is followed by the size of
+ the data in use in that stack, in bytes. */
+#ifdef YYLSP_NEEDED
+ /* This used to be a conditional around just the two extra args,
+ but that might be undefined if yyoverflow is a macro. */
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yyls1, size * sizeof (*yylsp),
+ &yystacksize);
+#else
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yystacksize);
+#endif
+
+ yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+ yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ {
+ yyerror("parser stack overflow");
+ return 2;
+ }
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+ yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
+ __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
+ yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
+ __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+ yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
+ __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + size - 1;
+ yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+ goto yybackup;
+ yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Reading a token: ");
+#endif
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Now at end of input.\n");
+#endif
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+ /* Give the individual parser a way to print the precise meaning
+ of a token, for further debugging info. */
+#ifdef YYPRINT
+ YYPRINT (stderr, yychar, yylval);
+#endif
+ fprintf (stderr, ")\n");
+ }
+#endif
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrlab;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ /* count tokens shifted since error; after three, turn off error status. */
+ if (yyerrstatus) yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+/* Do the default action for the current state. */
+yydefault:
+
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+
+/* Do a reduction. yyn is the number of a rule to reduce with. */
+yyreduce:
+ yylen = yyr2[yyn];
+ if (yylen > 0)
+ yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ int i;
+
+ fprintf (stderr, "Reducing via rule %d (line %d), ",
+ yyn, yyrline[yyn]);
+
+ /* Print the symbols being reduced, and their result. */
+ for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+ fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+ fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+ }
+#endif
+
+
+ switch (yyn) {
+
+case 1:
+#line 240 "objc-parse.y"
+{ if (pedantic)
+ pedwarn ("ANSI C forbids an empty source file");
+ finish_file ();
+ ;
+ break;}
+case 2:
+#line 245 "objc-parse.y"
+{
+ /* In case there were missing closebraces,
+ get us back to the global binding level. */
+ while (! global_bindings_p ())
+ poplevel (0, 0, 0);
+ finish_file ();
+ ;
+ break;}
+case 3:
+#line 259 "objc-parse.y"
+{yyval.ttype = NULL_TREE; ;
+ break;}
+case 5:
+#line 260 "objc-parse.y"
+{yyval.ttype = NULL_TREE; ;
+ break;}
+case 10:
+#line 268 "objc-parse.y"
+{ STRIP_NOPS (yyvsp[-2].ttype);
+ if ((TREE_CODE (yyvsp[-2].ttype) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (yyvsp[-2].ttype, 0)) == STRING_CST)
+ || TREE_CODE (yyvsp[-2].ttype) == STRING_CST)
+ assemble_asm (yyvsp[-2].ttype);
+ else
+ error ("argument of `asm' is not a constant string"); ;
+ break;}
+case 11:
+#line 276 "objc-parse.y"
+{ pedantic = yyvsp[-1].itype; ;
+ break;}
+case 12:
+#line 281 "objc-parse.y"
+{ if (pedantic)
+ error ("ANSI C forbids data definition with no type or storage class");
+ else if (!flag_traditional)
+ warning ("data definition has no type or storage class");
+
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 13:
+#line 291 "objc-parse.y"
+{ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 14:
+#line 296 "objc-parse.y"
+{ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 15:
+#line 301 "objc-parse.y"
+{ pedwarn ("empty declaration"); ;
+ break;}
+case 16:
+#line 303 "objc-parse.y"
+{ shadow_tag (yyvsp[-1].ttype); ;
+ break;}
+case 19:
+#line 307 "objc-parse.y"
+{ if (pedantic)
+ pedwarn ("ANSI C does not allow extra `;' outside of a function"); ;
+ break;}
+case 20:
+#line 313 "objc-parse.y"
+{ if (! start_function (current_declspecs, yyvsp[0].ttype,
+ prefix_attributes, NULL_TREE, 0))
+ YYERROR1;
+ reinit_parse_for_function (); ;
+ break;}
+case 21:
+#line 318 "objc-parse.y"
+{ store_parm_decls (); ;
+ break;}
+case 22:
+#line 320 "objc-parse.y"
+{ finish_function (0);
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-5].itype); ;
+ break;}
+case 23:
+#line 326 "objc-parse.y"
+{ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 24:
+#line 331 "objc-parse.y"
+{ if (! start_function (current_declspecs, yyvsp[0].ttype,
+ prefix_attributes, NULL_TREE, 0))
+ YYERROR1;
+ reinit_parse_for_function (); ;
+ break;}
+case 25:
+#line 336 "objc-parse.y"
+{ store_parm_decls (); ;
+ break;}
+case 26:
+#line 338 "objc-parse.y"
+{ finish_function (0);
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-5].itype); ;
+ break;}
+case 27:
+#line 344 "objc-parse.y"
+{ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 28:
+#line 349 "objc-parse.y"
+{ if (! start_function (NULL_TREE, yyvsp[0].ttype,
+ prefix_attributes, NULL_TREE, 0))
+ YYERROR1;
+ reinit_parse_for_function (); ;
+ break;}
+case 29:
+#line 354 "objc-parse.y"
+{ store_parm_decls (); ;
+ break;}
+case 30:
+#line 356 "objc-parse.y"
+{ finish_function (0);
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-5].itype); ;
+ break;}
+case 31:
+#line 362 "objc-parse.y"
+{ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 36:
+#line 376 "objc-parse.y"
+{ yyval.code = ADDR_EXPR; ;
+ break;}
+case 37:
+#line 378 "objc-parse.y"
+{ yyval.code = NEGATE_EXPR; ;
+ break;}
+case 38:
+#line 380 "objc-parse.y"
+{ yyval.code = CONVERT_EXPR; ;
+ break;}
+case 39:
+#line 382 "objc-parse.y"
+{ yyval.code = PREINCREMENT_EXPR; ;
+ break;}
+case 40:
+#line 384 "objc-parse.y"
+{ yyval.code = PREDECREMENT_EXPR; ;
+ break;}
+case 41:
+#line 386 "objc-parse.y"
+{ yyval.code = BIT_NOT_EXPR; ;
+ break;}
+case 42:
+#line 388 "objc-parse.y"
+{ yyval.code = TRUTH_NOT_EXPR; ;
+ break;}
+case 43:
+#line 392 "objc-parse.y"
+{ yyval.ttype = build_compound_expr (yyvsp[0].ttype); ;
+ break;}
+case 44:
+#line 397 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 46:
+#line 403 "objc-parse.y"
+{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ;
+ break;}
+case 47:
+#line 405 "objc-parse.y"
+{ chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ;
+ break;}
+case 49:
+#line 411 "objc-parse.y"
+{ yyval.ttype = build_indirect_ref (yyvsp[0].ttype, "unary *"); ;
+ break;}
+case 50:
+#line 414 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype;
+ pedantic = yyvsp[-1].itype; ;
+ break;}
+case 51:
+#line 417 "objc-parse.y"
+{ yyval.ttype = build_unary_op (yyvsp[-1].code, yyvsp[0].ttype, 0);
+ overflow_warning (yyval.ttype); ;
+ break;}
+case 52:
+#line 421 "objc-parse.y"
+{ tree label = lookup_label (yyvsp[0].ttype);
+ if (pedantic)
+ pedwarn ("ANSI C forbids `&&'");
+ if (label == 0)
+ yyval.ttype = null_pointer_node;
+ else
+ {
+ TREE_USED (label) = 1;
+ yyval.ttype = build1 (ADDR_EXPR, ptr_type_node, label);
+ TREE_CONSTANT (yyval.ttype) = 1;
+ }
+ ;
+ break;}
+case 53:
+#line 449 "objc-parse.y"
+{ skip_evaluation--;
+ if (TREE_CODE (yyvsp[0].ttype) == COMPONENT_REF
+ && DECL_C_BIT_FIELD (TREE_OPERAND (yyvsp[0].ttype, 1)))
+ error ("`sizeof' applied to a bit-field");
+ yyval.ttype = c_sizeof (TREE_TYPE (yyvsp[0].ttype)); ;
+ break;}
+case 54:
+#line 455 "objc-parse.y"
+{ skip_evaluation--;
+ yyval.ttype = c_sizeof (groktypename (yyvsp[-1].ttype)); ;
+ break;}
+case 55:
+#line 458 "objc-parse.y"
+{ skip_evaluation--;
+ yyval.ttype = c_alignof_expr (yyvsp[0].ttype); ;
+ break;}
+case 56:
+#line 461 "objc-parse.y"
+{ skip_evaluation--;
+ yyval.ttype = c_alignof (groktypename (yyvsp[-1].ttype)); ;
+ break;}
+case 57:
+#line 464 "objc-parse.y"
+{ yyval.ttype = build_unary_op (REALPART_EXPR, yyvsp[0].ttype, 0); ;
+ break;}
+case 58:
+#line 466 "objc-parse.y"
+{ yyval.ttype = build_unary_op (IMAGPART_EXPR, yyvsp[0].ttype, 0); ;
+ break;}
+case 59:
+#line 470 "objc-parse.y"
+{ skip_evaluation++; ;
+ break;}
+case 60:
+#line 474 "objc-parse.y"
+{ skip_evaluation++; ;
+ break;}
+case 62:
+#line 480 "objc-parse.y"
+{ tree type = groktypename (yyvsp[-2].ttype);
+ yyval.ttype = build_c_cast (type, yyvsp[0].ttype); ;
+ break;}
+case 63:
+#line 483 "objc-parse.y"
+{ start_init (NULL_TREE, NULL, 0);
+ yyvsp[-2].ttype = groktypename (yyvsp[-2].ttype);
+ really_start_incremental_init (yyvsp[-2].ttype); ;
+ break;}
+case 64:
+#line 487 "objc-parse.y"
+{ char *name;
+ tree result = pop_init_level (0);
+ tree type = yyvsp[-5].ttype;
+ finish_init ();
+
+ if (pedantic)
+ pedwarn ("ANSI C forbids constructor expressions");
+ if (TYPE_NAME (type) != 0)
+ {
+ if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
+ name = IDENTIFIER_POINTER (TYPE_NAME (type));
+ else
+ name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+ }
+ else
+ name = "";
+ yyval.ttype = result;
+ if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
+ {
+ int failure = complete_array_type (type, yyval.ttype, 1);
+ if (failure)
+ abort ();
+ }
+ ;
+ break;}
+case 66:
+#line 516 "objc-parse.y"
+{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 67:
+#line 518 "objc-parse.y"
+{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 68:
+#line 520 "objc-parse.y"
+{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 69:
+#line 522 "objc-parse.y"
+{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 70:
+#line 524 "objc-parse.y"
+{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 71:
+#line 526 "objc-parse.y"
+{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 72:
+#line 528 "objc-parse.y"
+{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 73:
+#line 530 "objc-parse.y"
+{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 74:
+#line 532 "objc-parse.y"
+{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 75:
+#line 534 "objc-parse.y"
+{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 76:
+#line 536 "objc-parse.y"
+{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 77:
+#line 538 "objc-parse.y"
+{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 78:
+#line 540 "objc-parse.y"
+{ yyvsp[-1].ttype = truthvalue_conversion (default_conversion (yyvsp[-1].ttype));
+ skip_evaluation += yyvsp[-1].ttype == boolean_false_node; ;
+ break;}
+case 79:
+#line 543 "objc-parse.y"
+{ skip_evaluation -= yyvsp[-3].ttype == boolean_false_node;
+ yyval.ttype = parser_build_binary_op (TRUTH_ANDIF_EXPR, yyvsp[-3].ttype, yyvsp[0].ttype); ;
+ break;}
+case 80:
+#line 546 "objc-parse.y"
+{ yyvsp[-1].ttype = truthvalue_conversion (default_conversion (yyvsp[-1].ttype));
+ skip_evaluation += yyvsp[-1].ttype == boolean_true_node; ;
+ break;}
+case 81:
+#line 549 "objc-parse.y"
+{ skip_evaluation -= yyvsp[-3].ttype == boolean_true_node;
+ yyval.ttype = parser_build_binary_op (TRUTH_ORIF_EXPR, yyvsp[-3].ttype, yyvsp[0].ttype); ;
+ break;}
+case 82:
+#line 552 "objc-parse.y"
+{ yyvsp[-1].ttype = truthvalue_conversion (default_conversion (yyvsp[-1].ttype));
+ skip_evaluation += yyvsp[-1].ttype == boolean_false_node; ;
+ break;}
+case 83:
+#line 555 "objc-parse.y"
+{ skip_evaluation += ((yyvsp[-4].ttype == boolean_true_node)
+ - (yyvsp[-4].ttype == boolean_false_node)); ;
+ break;}
+case 84:
+#line 558 "objc-parse.y"
+{ skip_evaluation -= yyvsp[-6].ttype == boolean_true_node;
+ yyval.ttype = build_conditional_expr (yyvsp[-6].ttype, yyvsp[-3].ttype, yyvsp[0].ttype); ;
+ break;}
+case 85:
+#line 561 "objc-parse.y"
+{ if (pedantic)
+ pedwarn ("ANSI C forbids omitting the middle term of a ?: expression");
+ /* Make sure first operand is calculated only once. */
+ yyvsp[0].ttype = save_expr (yyvsp[-1].ttype);
+ yyvsp[-1].ttype = truthvalue_conversion (default_conversion (yyvsp[0].ttype));
+ skip_evaluation += yyvsp[-1].ttype == boolean_true_node; ;
+ break;}
+case 86:
+#line 568 "objc-parse.y"
+{ skip_evaluation -= yyvsp[-4].ttype == boolean_true_node;
+ yyval.ttype = build_conditional_expr (yyvsp[-4].ttype, yyvsp[-3].ttype, yyvsp[0].ttype); ;
+ break;}
+case 87:
+#line 571 "objc-parse.y"
+{ yyval.ttype = build_modify_expr (yyvsp[-2].ttype, NOP_EXPR, yyvsp[0].ttype);
+ C_SET_EXP_ORIGINAL_CODE (yyval.ttype, MODIFY_EXPR); ;
+ break;}
+case 88:
+#line 574 "objc-parse.y"
+{ yyval.ttype = build_modify_expr (yyvsp[-2].ttype, yyvsp[-1].code, yyvsp[0].ttype);
+ /* This inhibits warnings in truthvalue_conversion. */
+ C_SET_EXP_ORIGINAL_CODE (yyval.ttype, ERROR_MARK); ;
+ break;}
+case 89:
+#line 581 "objc-parse.y"
+{
+ yyval.ttype = lastiddecl;
+ if (!yyval.ttype || yyval.ttype == error_mark_node)
+ {
+ if (yychar == YYEMPTY)
+ yychar = YYLEX;
+ if (yychar == '(')
+ {
+ tree decl;
+
+ if (objc_receiver_context
+ && ! (objc_receiver_context
+ && strcmp (IDENTIFIER_POINTER (yyvsp[0].ttype), "super")))
+ /* we have a message to super */
+ yyval.ttype = get_super_receiver ();
+ else if (objc_method_context
+ && (decl = is_ivar (objc_ivar_chain, yyvsp[0].ttype)))
+ {
+ if (is_private (decl))
+ yyval.ttype = error_mark_node;
+ else
+ yyval.ttype = build_ivar_reference (yyvsp[0].ttype);
+ }
+ else
+ {
+ /* Ordinary implicit function declaration. */
+ yyval.ttype = implicitly_declare (yyvsp[0].ttype);
+ assemble_external (yyval.ttype);
+ TREE_USED (yyval.ttype) = 1;
+ }
+ }
+ else if (current_function_decl == 0)
+ {
+ error ("`%s' undeclared here (not in a function)",
+ IDENTIFIER_POINTER (yyvsp[0].ttype));
+ yyval.ttype = error_mark_node;
+ }
+ else
+ {
+ tree decl;
+
+ if (objc_receiver_context
+ && ! strcmp (IDENTIFIER_POINTER (yyvsp[0].ttype), "super"))
+ /* we have a message to super */
+ yyval.ttype = get_super_receiver ();
+ else if (objc_method_context
+ && (decl = is_ivar (objc_ivar_chain, yyvsp[0].ttype)))
+ {
+ if (is_private (decl))
+ yyval.ttype = error_mark_node;
+ else
+ yyval.ttype = build_ivar_reference (yyvsp[0].ttype);
+ }
+ else
+ {
+ if (IDENTIFIER_GLOBAL_VALUE (yyvsp[0].ttype) != error_mark_node
+ || IDENTIFIER_ERROR_LOCUS (yyvsp[0].ttype) != current_function_decl)
+ {
+ error ("`%s' undeclared (first use this function)",
+ IDENTIFIER_POINTER (yyvsp[0].ttype));
+
+ if (! undeclared_variable_notice)
+ {
+ error ("(Each undeclared identifier is reported only once");
+ error ("for each function it appears in.)");
+ undeclared_variable_notice = 1;
+ }
+ }
+ yyval.ttype = error_mark_node;
+ /* Prevent repeated error messages. */
+ IDENTIFIER_GLOBAL_VALUE (yyvsp[0].ttype) = error_mark_node;
+ IDENTIFIER_ERROR_LOCUS (yyvsp[0].ttype) = current_function_decl;
+ }
+ }
+ }
+ else if (TREE_TYPE (yyval.ttype) == error_mark_node)
+ yyval.ttype = error_mark_node;
+ else if (C_DECL_ANTICIPATED (yyval.ttype))
+ {
+ /* The first time we see a build-in function used,
+ if it has not been declared. */
+ C_DECL_ANTICIPATED (yyval.ttype) = 0;
+ if (yychar == YYEMPTY)
+ yychar = YYLEX;
+ if (yychar == '(')
+ {
+ /* Omit the implicit declaration we
+ would ordinarily do, so we don't lose
+ the actual built in type.
+ But print a diagnostic for the mismatch. */
+ if (objc_method_context
+ && is_ivar (objc_ivar_chain, yyvsp[0].ttype))
+ error ("Instance variable `%s' implicitly declared as function",
+ IDENTIFIER_POINTER (DECL_NAME (yyval.ttype)));
+ else
+ if (TREE_CODE (yyval.ttype) != FUNCTION_DECL)
+ error ("`%s' implicitly declared as function",
+ IDENTIFIER_POINTER (DECL_NAME (yyval.ttype)));
+ else if ((TYPE_MODE (TREE_TYPE (TREE_TYPE (yyval.ttype)))
+ != TYPE_MODE (integer_type_node))
+ && (TREE_TYPE (TREE_TYPE (yyval.ttype))
+ != void_type_node))
+ pedwarn ("type mismatch in implicit declaration for built-in function `%s'",
+ IDENTIFIER_POINTER (DECL_NAME (yyval.ttype)));
+ /* If it really returns void, change that to int. */
+ if (TREE_TYPE (TREE_TYPE (yyval.ttype)) == void_type_node)
+ TREE_TYPE (yyval.ttype)
+ = build_function_type (integer_type_node,
+ TYPE_ARG_TYPES (TREE_TYPE (yyval.ttype)));
+ }
+ else
+ pedwarn ("built-in function `%s' used without declaration",
+ IDENTIFIER_POINTER (DECL_NAME (yyval.ttype)));
+
+ /* Do what we would ordinarily do when a fn is used. */
+ assemble_external (yyval.ttype);
+ TREE_USED (yyval.ttype) = 1;
+ }
+ else
+ {
+ assemble_external (yyval.ttype);
+ TREE_USED (yyval.ttype) = 1;
+ /* we have a definition - still check if iVariable */
+
+ if (!objc_receiver_context
+ || (objc_receiver_context
+ && strcmp (IDENTIFIER_POINTER (yyvsp[0].ttype), "super")))
+ {
+ tree decl;
+
+ if (objc_method_context
+ && (decl = is_ivar (objc_ivar_chain, yyvsp[0].ttype)))
+ {
+ if (IDENTIFIER_LOCAL_VALUE (yyvsp[0].ttype))
+ warning ("local declaration of `%s' hides instance variable",
+ IDENTIFIER_POINTER (yyvsp[0].ttype));
+ else
+ {
+ if (is_private (decl))
+ yyval.ttype = error_mark_node;
+ else
+ yyval.ttype = build_ivar_reference (yyvsp[0].ttype);
+ }
+ }
+ }
+ else /* we have a message to super */
+ yyval.ttype = get_super_receiver ();
+ }
+
+ if (TREE_CODE (yyval.ttype) == CONST_DECL)
+ {
+ yyval.ttype = DECL_INITIAL (yyval.ttype);
+ /* This is to prevent an enum whose value is 0
+ from being considered a null pointer constant. */
+ yyval.ttype = build1 (NOP_EXPR, TREE_TYPE (yyval.ttype), yyval.ttype);
+ TREE_CONSTANT (yyval.ttype) = 1;
+ }
+ ;
+ break;}
+case 91:
+#line 741 "objc-parse.y"
+{ yyval.ttype = combine_strings (yyvsp[0].ttype); ;
+ break;}
+case 92:
+#line 743 "objc-parse.y"
+{ char class = TREE_CODE_CLASS (TREE_CODE (yyvsp[-1].ttype));
+ if (class == 'e' || class == '1'
+ || class == '2' || class == '<')
+ C_SET_EXP_ORIGINAL_CODE (yyvsp[-1].ttype, ERROR_MARK);
+ yyval.ttype = yyvsp[-1].ttype; ;
+ break;}
+case 93:
+#line 749 "objc-parse.y"
+{ yyval.ttype = error_mark_node; ;
+ break;}
+case 94:
+#line 751 "objc-parse.y"
+{ if (current_function_decl == 0)
+ {
+ error ("braced-group within expression allowed only inside a function");
+ YYERROR;
+ }
+ /* We must force a BLOCK for this level
+ so that, if it is not expanded later,
+ there is a way to turn off the entire subtree of blocks
+ that are contained in it. */
+ keep_next_level ();
+ push_iterator_stack ();
+ push_label_level ();
+ yyval.ttype = expand_start_stmt_expr (); ;
+ break;}
+case 95:
+#line 765 "objc-parse.y"
+{ tree rtl_exp;
+ if (pedantic)
+ pedwarn ("ANSI C forbids braced-groups within expressions");
+ pop_iterator_stack ();
+ pop_label_level ();
+ rtl_exp = expand_end_stmt_expr (yyvsp[-2].ttype);
+ /* The statements have side effects, so the group does. */
+ TREE_SIDE_EFFECTS (rtl_exp) = 1;
+
+ if (TREE_CODE (yyvsp[-1].ttype) == BLOCK)
+ {
+ /* Make a BIND_EXPR for the BLOCK already made. */
+ yyval.ttype = build (BIND_EXPR, TREE_TYPE (rtl_exp),
+ NULL_TREE, rtl_exp, yyvsp[-1].ttype);
+ /* Remove the block from the tree at this point.
+ It gets put back at the proper place
+ when the BIND_EXPR is expanded. */
+ delete_block (yyvsp[-1].ttype);
+ }
+ else
+ yyval.ttype = yyvsp[-1].ttype;
+ ;
+ break;}
+case 96:
+#line 788 "objc-parse.y"
+{ yyval.ttype = build_function_call (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 97:
+#line 790 "objc-parse.y"
+{ yyval.ttype = build_array_ref (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 98:
+#line 792 "objc-parse.y"
+{
+ if (doing_objc_thang)
+ {
+ if (is_public (yyvsp[-2].ttype, yyvsp[0].ttype))
+ yyval.ttype = build_component_ref (yyvsp[-2].ttype, yyvsp[0].ttype);
+ else
+ yyval.ttype = error_mark_node;
+ }
+ else
+ yyval.ttype = build_component_ref (yyvsp[-2].ttype, yyvsp[0].ttype);
+ ;
+ break;}
+case 99:
+#line 804 "objc-parse.y"
+{
+ tree expr = build_indirect_ref (yyvsp[-2].ttype, "->");
+
+ if (doing_objc_thang)
+ {
+ if (is_public (expr, yyvsp[0].ttype))
+ yyval.ttype = build_component_ref (expr, yyvsp[0].ttype);
+ else
+ yyval.ttype = error_mark_node;
+ }
+ else
+ yyval.ttype = build_component_ref (expr, yyvsp[0].ttype);
+ ;
+ break;}
+case 100:
+#line 818 "objc-parse.y"
+{ yyval.ttype = build_unary_op (POSTINCREMENT_EXPR, yyvsp[-1].ttype, 0); ;
+ break;}
+case 101:
+#line 820 "objc-parse.y"
+{ yyval.ttype = build_unary_op (POSTDECREMENT_EXPR, yyvsp[-1].ttype, 0); ;
+ break;}
+case 102:
+#line 822 "objc-parse.y"
+{ yyval.ttype = build_message_expr (yyvsp[0].ttype); ;
+ break;}
+case 103:
+#line 824 "objc-parse.y"
+{ yyval.ttype = build_selector_expr (yyvsp[0].ttype); ;
+ break;}
+case 104:
+#line 826 "objc-parse.y"
+{ yyval.ttype = build_protocol_expr (yyvsp[0].ttype); ;
+ break;}
+case 105:
+#line 828 "objc-parse.y"
+{ yyval.ttype = build_encode_expr (yyvsp[0].ttype); ;
+ break;}
+case 106:
+#line 830 "objc-parse.y"
+{ yyval.ttype = build_objc_string_object (yyvsp[0].ttype); ;
+ break;}
+case 108:
+#line 837 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); ;
+ break;}
+case 110:
+#line 845 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); ;
+ break;}
+case 113:
+#line 853 "objc-parse.y"
+{ c_mark_varargs ();
+ if (pedantic)
+ pedwarn ("ANSI C does not permit use of `varargs.h'"); ;
+ break;}
+case 114:
+#line 863 "objc-parse.y"
+{ ;
+ break;}
+case 119:
+#line 879 "objc-parse.y"
+{ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 120:
+#line 884 "objc-parse.y"
+{ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 121:
+#line 889 "objc-parse.y"
+{ shadow_tag_warned (yyvsp[-1].ttype, 1);
+ pedwarn ("empty declaration"); ;
+ break;}
+case 122:
+#line 892 "objc-parse.y"
+{ pedwarn ("empty declaration"); ;
+ break;}
+case 123:
+#line 901 "objc-parse.y"
+{ ;
+ break;}
+case 128:
+#line 916 "objc-parse.y"
+{ yyval.itype = suspend_momentary ();
+ pending_xref_error ();
+ declspec_stack = tree_cons (prefix_attributes,
+ current_declspecs,
+ declspec_stack);
+ split_specs_attrs (yyvsp[0].ttype,
+ &current_declspecs, &prefix_attributes); ;
+ break;}
+case 129:
+#line 927 "objc-parse.y"
+{ prefix_attributes = chainon (prefix_attributes, yyvsp[0].ttype); ;
+ break;}
+case 130:
+#line 932 "objc-parse.y"
+{ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 131:
+#line 937 "objc-parse.y"
+{ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 132:
+#line 942 "objc-parse.y"
+{ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-1].itype); ;
+ break;}
+case 133:
+#line 947 "objc-parse.y"
+{ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-1].itype); ;
+ break;}
+case 134:
+#line 952 "objc-parse.y"
+{ shadow_tag (yyvsp[-1].ttype); ;
+ break;}
+case 135:
+#line 954 "objc-parse.y"
+{ pedwarn ("empty declaration"); ;
+ break;}
+case 136:
+#line 956 "objc-parse.y"
+{ pedantic = yyvsp[-1].itype; ;
+ break;}
+case 137:
+#line 966 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype); ;
+ break;}
+case 138:
+#line 968 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[0].ttype, tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[-2].ttype)); ;
+ break;}
+case 139:
+#line 972 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 140:
+#line 974 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 141:
+#line 976 "objc-parse.y"
+{ if (extra_warnings)
+ warning ("`%s' is not at beginning of declaration",
+ IDENTIFIER_POINTER (yyvsp[0].ttype));
+ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 142:
+#line 981 "objc-parse.y"
+{ yyval.ttype = tree_cons (yyvsp[0].ttype, NULL_TREE, yyvsp[-1].ttype); ;
+ break;}
+case 143:
+#line 986 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype); ;
+ break;}
+case 144:
+#line 988 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[0].ttype, tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[-2].ttype)); ;
+ break;}
+case 145:
+#line 993 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 146:
+#line 995 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 147:
+#line 997 "objc-parse.y"
+{ if (extra_warnings)
+ warning ("`%s' is not at beginning of declaration",
+ IDENTIFIER_POINTER (yyvsp[0].ttype));
+ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 148:
+#line 1010 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype; ;
+ break;}
+case 149:
+#line 1012 "objc-parse.y"
+{ yyval.ttype = tree_cons (yyvsp[0].ttype, NULL_TREE, NULL_TREE); ;
+ break;}
+case 150:
+#line 1014 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[0].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 151:
+#line 1016 "objc-parse.y"
+{ yyval.ttype = tree_cons (yyvsp[0].ttype, NULL_TREE, yyvsp[-1].ttype); ;
+ break;}
+case 152:
+#line 1021 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE);
+ TREE_STATIC (yyval.ttype) = 1; ;
+ break;}
+case 153:
+#line 1024 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ;
+ break;}
+case 154:
+#line 1026 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype);
+ TREE_STATIC (yyval.ttype) = 1; ;
+ break;}
+case 155:
+#line 1029 "objc-parse.y"
+{ if (extra_warnings && TREE_STATIC (yyvsp[-1].ttype))
+ warning ("`%s' is not at beginning of declaration",
+ IDENTIFIER_POINTER (yyvsp[0].ttype));
+ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype);
+ TREE_STATIC (yyval.ttype) = TREE_STATIC (yyvsp[-1].ttype); ;
+ break;}
+case 156:
+#line 1043 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype); ;
+ break;}
+case 157:
+#line 1045 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[0].ttype, tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[-2].ttype)); ;
+ break;}
+case 158:
+#line 1049 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 159:
+#line 1051 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 162:
+#line 1061 "objc-parse.y"
+{ /* For a typedef name, record the meaning, not the name.
+ In case of `foo foo, bar;'. */
+ yyval.ttype = lookup_name (yyvsp[0].ttype); ;
+ break;}
+case 163:
+#line 1065 "objc-parse.y"
+{ yyval.ttype = get_static_reference (yyvsp[-1].ttype, yyvsp[0].ttype); ;
+ break;}
+case 164:
+#line 1067 "objc-parse.y"
+{ yyval.ttype = get_object_reference (yyvsp[0].ttype); ;
+ break;}
+case 165:
+#line 1072 "objc-parse.y"
+{ yyval.ttype = get_object_reference (yyvsp[0].ttype); ;
+ break;}
+case 166:
+#line 1074 "objc-parse.y"
+{ yyval.ttype = TREE_TYPE (yyvsp[-1].ttype); ;
+ break;}
+case 167:
+#line 1076 "objc-parse.y"
+{ yyval.ttype = groktypename (yyvsp[-1].ttype); ;
+ break;}
+case 175:
+#line 1098 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 176:
+#line 1100 "objc-parse.y"
+{ if (TREE_CHAIN (yyvsp[-1].ttype)) yyvsp[-1].ttype = combine_strings (yyvsp[-1].ttype);
+ yyval.ttype = yyvsp[-1].ttype;
+ ;
+ break;}
+case 177:
+#line 1107 "objc-parse.y"
+{ yyval.ttype = start_decl (yyvsp[-3].ttype, current_declspecs, 1,
+ yyvsp[-1].ttype, prefix_attributes);
+ start_init (yyval.ttype, yyvsp[-2].ttype, global_bindings_p ()); ;
+ break;}
+case 178:
+#line 1112 "objc-parse.y"
+{ finish_init ();
+ finish_decl (yyvsp[-1].ttype, yyvsp[0].ttype, yyvsp[-4].ttype); ;
+ break;}
+case 179:
+#line 1115 "objc-parse.y"
+{ tree d = start_decl (yyvsp[-2].ttype, current_declspecs, 0,
+ yyvsp[0].ttype, prefix_attributes);
+ finish_decl (d, NULL_TREE, yyvsp[-1].ttype);
+ ;
+ break;}
+case 180:
+#line 1123 "objc-parse.y"
+{ yyval.ttype = start_decl (yyvsp[-3].ttype, current_declspecs, 1,
+ yyvsp[-1].ttype, prefix_attributes);
+ start_init (yyval.ttype, yyvsp[-2].ttype, global_bindings_p ()); ;
+ break;}
+case 181:
+#line 1128 "objc-parse.y"
+{ finish_init ();
+ decl_attributes (yyvsp[-1].ttype, yyvsp[-3].ttype, prefix_attributes);
+ finish_decl (yyvsp[-1].ttype, yyvsp[0].ttype, yyvsp[-4].ttype); ;
+ break;}
+case 182:
+#line 1132 "objc-parse.y"
+{ tree d = start_decl (yyvsp[-2].ttype, current_declspecs, 0,
+ yyvsp[0].ttype, prefix_attributes);
+ finish_decl (d, NULL_TREE, yyvsp[-1].ttype); ;
+ break;}
+case 183:
+#line 1140 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 184:
+#line 1142 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype; ;
+ break;}
+case 185:
+#line 1147 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype; ;
+ break;}
+case 186:
+#line 1149 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); ;
+ break;}
+case 187:
+#line 1154 "objc-parse.y"
+{ yyval.ttype = yyvsp[-2].ttype; ;
+ break;}
+case 188:
+#line 1159 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype; ;
+ break;}
+case 189:
+#line 1161 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 190:
+#line 1166 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 191:
+#line 1168 "objc-parse.y"
+{ yyval.ttype = build_tree_list (yyvsp[0].ttype, NULL_TREE); ;
+ break;}
+case 192:
+#line 1170 "objc-parse.y"
+{ yyval.ttype = build_tree_list (yyvsp[-3].ttype, build_tree_list (NULL_TREE, yyvsp[-1].ttype)); ;
+ break;}
+case 193:
+#line 1172 "objc-parse.y"
+{ yyval.ttype = build_tree_list (yyvsp[-5].ttype, tree_cons (NULL_TREE, yyvsp[-3].ttype, yyvsp[-1].ttype)); ;
+ break;}
+case 194:
+#line 1174 "objc-parse.y"
+{ yyval.ttype = build_tree_list (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 200:
+#line 1192 "objc-parse.y"
+{ really_start_incremental_init (NULL_TREE);
+ /* Note that the call to clear_momentary
+ is in process_init_element. */
+ push_momentary (); ;
+ break;}
+case 201:
+#line 1197 "objc-parse.y"
+{ yyval.ttype = pop_init_level (0);
+ if (yyval.ttype == error_mark_node
+ && ! (yychar == STRING || yychar == CONSTANT))
+ pop_momentary ();
+ else
+ pop_momentary_nofree (); ;
+ break;}
+case 202:
+#line 1205 "objc-parse.y"
+{ yyval.ttype = error_mark_node; ;
+ break;}
+case 203:
+#line 1211 "objc-parse.y"
+{ if (pedantic)
+ pedwarn ("ANSI C forbids empty initializer braces"); ;
+ break;}
+case 207:
+#line 1225 "objc-parse.y"
+{ process_init_element (yyvsp[0].ttype); ;
+ break;}
+case 208:
+#line 1227 "objc-parse.y"
+{ push_init_level (0); ;
+ break;}
+case 209:
+#line 1229 "objc-parse.y"
+{ process_init_element (pop_init_level (0)); ;
+ break;}
+case 211:
+#line 1235 "objc-parse.y"
+{ set_init_label (yyvsp[-1].ttype); ;
+ break;}
+case 213:
+#line 1238 "objc-parse.y"
+{ set_init_label (yyvsp[-1].ttype); ;
+ break;}
+case 215:
+#line 1244 "objc-parse.y"
+{ push_c_function_context ();
+ if (! start_function (current_declspecs, yyvsp[0].ttype,
+ prefix_attributes, NULL_TREE, 1))
+ {
+ pop_c_function_context ();
+ YYERROR1;
+ }
+ reinit_parse_for_function (); ;
+ break;}
+case 216:
+#line 1253 "objc-parse.y"
+{ store_parm_decls (); ;
+ break;}
+case 217:
+#line 1261 "objc-parse.y"
+{ finish_function (1);
+ pop_c_function_context (); ;
+ break;}
+case 218:
+#line 1267 "objc-parse.y"
+{ push_c_function_context ();
+ if (! start_function (current_declspecs, yyvsp[0].ttype,
+ prefix_attributes, NULL_TREE, 1))
+ {
+ pop_c_function_context ();
+ YYERROR1;
+ }
+ reinit_parse_for_function (); ;
+ break;}
+case 219:
+#line 1276 "objc-parse.y"
+{ store_parm_decls (); ;
+ break;}
+case 220:
+#line 1284 "objc-parse.y"
+{ finish_function (1);
+ pop_c_function_context (); ;
+ break;}
+case 223:
+#line 1300 "objc-parse.y"
+{ yyval.ttype = yyvsp[-1].ttype; ;
+ break;}
+case 224:
+#line 1302 "objc-parse.y"
+{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ;
+ break;}
+case 225:
+#line 1307 "objc-parse.y"
+{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 226:
+#line 1309 "objc-parse.y"
+{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ;
+ break;}
+case 227:
+#line 1311 "objc-parse.y"
+{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
+ break;}
+case 228:
+#line 1318 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype; ;
+ break;}
+case 231:
+#line 1330 "objc-parse.y"
+{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ;
+ break;}
+case 232:
+#line 1335 "objc-parse.y"
+{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 233:
+#line 1337 "objc-parse.y"
+{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ;
+ break;}
+case 234:
+#line 1339 "objc-parse.y"
+{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
+ break;}
+case 235:
+#line 1346 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype; ;
+ break;}
+case 237:
+#line 1355 "objc-parse.y"
+{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ;
+ break;}
+case 238:
+#line 1360 "objc-parse.y"
+{ yyval.ttype = yyvsp[-1].ttype; ;
+ break;}
+case 239:
+#line 1362 "objc-parse.y"
+{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
+ break;}
+case 240:
+#line 1364 "objc-parse.y"
+{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 241:
+#line 1366 "objc-parse.y"
+{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ;
+ break;}
+case 242:
+#line 1373 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype; ;
+ break;}
+case 244:
+#line 1379 "objc-parse.y"
+{ yyval.ttype = start_struct (RECORD_TYPE, yyvsp[-1].ttype);
+ /* Start scope of tag before parsing components. */
+ ;
+ break;}
+case 245:
+#line 1383 "objc-parse.y"
+{ yyval.ttype = finish_struct (yyvsp[-3].ttype, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 246:
+#line 1385 "objc-parse.y"
+{ yyval.ttype = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
+ yyvsp[-2].ttype, yyvsp[0].ttype);
+ ;
+ break;}
+case 247:
+#line 1389 "objc-parse.y"
+{ yyval.ttype = xref_tag (RECORD_TYPE, yyvsp[0].ttype); ;
+ break;}
+case 248:
+#line 1391 "objc-parse.y"
+{ yyval.ttype = start_struct (UNION_TYPE, yyvsp[-1].ttype); ;
+ break;}
+case 249:
+#line 1393 "objc-parse.y"
+{ yyval.ttype = finish_struct (yyvsp[-3].ttype, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 250:
+#line 1395 "objc-parse.y"
+{ yyval.ttype = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
+ yyvsp[-2].ttype, yyvsp[0].ttype);
+ ;
+ break;}
+case 251:
+#line 1399 "objc-parse.y"
+{ yyval.ttype = xref_tag (UNION_TYPE, yyvsp[0].ttype); ;
+ break;}
+case 252:
+#line 1401 "objc-parse.y"
+{ yyvsp[0].itype = suspend_momentary ();
+ yyval.ttype = start_enum (yyvsp[-1].ttype); ;
+ break;}
+case 253:
+#line 1404 "objc-parse.y"
+{ yyval.ttype = finish_enum (yyvsp[-4].ttype, nreverse (yyvsp[-3].ttype), yyvsp[0].ttype);
+ resume_momentary (yyvsp[-5].itype); ;
+ break;}
+case 254:
+#line 1407 "objc-parse.y"
+{ yyvsp[0].itype = suspend_momentary ();
+ yyval.ttype = start_enum (NULL_TREE); ;
+ break;}
+case 255:
+#line 1410 "objc-parse.y"
+{ yyval.ttype = finish_enum (yyvsp[-4].ttype, nreverse (yyvsp[-3].ttype), yyvsp[0].ttype);
+ resume_momentary (yyvsp[-5].itype); ;
+ break;}
+case 256:
+#line 1413 "objc-parse.y"
+{ yyval.ttype = xref_tag (ENUMERAL_TYPE, yyvsp[0].ttype); ;
+ break;}
+case 260:
+#line 1424 "objc-parse.y"
+{ if (pedantic) pedwarn ("comma at end of enumerator list"); ;
+ break;}
+case 261:
+#line 1429 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype; ;
+ break;}
+case 262:
+#line 1431 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype);
+ pedwarn ("no semicolon at end of struct or union"); ;
+ break;}
+case 263:
+#line 1436 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 264:
+#line 1438 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 265:
+#line 1440 "objc-parse.y"
+{ if (pedantic)
+ pedwarn ("extra semicolon in struct or union specified"); ;
+ break;}
+case 266:
+#line 1444 "objc-parse.y"
+{
+ tree interface = lookup_interface (yyvsp[-1].ttype);
+
+ if (interface)
+ yyval.ttype = get_class_ivars (interface);
+ else
+ {
+ error ("Cannot find interface declaration for `%s'",
+ IDENTIFIER_POINTER (yyvsp[-1].ttype));
+ yyval.ttype = NULL_TREE;
+ }
+ ;
+ break;}
+case 267:
+#line 1469 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype;
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-1].itype); ;
+ break;}
+case 268:
+#line 1475 "objc-parse.y"
+{ if (pedantic)
+ pedwarn ("ANSI C forbids member declarations with no members");
+ shadow_tag(yyvsp[0].ttype);
+ yyval.ttype = NULL_TREE; ;
+ break;}
+case 269:
+#line 1480 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype;
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-1].itype); ;
+ break;}
+case 270:
+#line 1486 "objc-parse.y"
+{ if (pedantic)
+ pedwarn ("ANSI C forbids member declarations with no members");
+ shadow_tag(yyvsp[0].ttype);
+ yyval.ttype = NULL_TREE; ;
+ break;}
+case 271:
+#line 1491 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 272:
+#line 1493 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype;
+ pedantic = yyvsp[-1].itype; ;
+ break;}
+case 274:
+#line 1500 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 275:
+#line 1505 "objc-parse.y"
+{ yyval.ttype = grokfield (yyvsp[-3].filename, yyvsp[-2].lineno, yyvsp[-1].ttype, current_declspecs, NULL_TREE);
+ decl_attributes (yyval.ttype, yyvsp[0].ttype, prefix_attributes); ;
+ break;}
+case 276:
+#line 1509 "objc-parse.y"
+{ yyval.ttype = grokfield (yyvsp[-5].filename, yyvsp[-4].lineno, yyvsp[-3].ttype, current_declspecs, yyvsp[-1].ttype);
+ decl_attributes (yyval.ttype, yyvsp[0].ttype, prefix_attributes); ;
+ break;}
+case 277:
+#line 1512 "objc-parse.y"
+{ yyval.ttype = grokfield (yyvsp[-4].filename, yyvsp[-3].lineno, NULL_TREE, current_declspecs, yyvsp[-1].ttype);
+ decl_attributes (yyval.ttype, yyvsp[0].ttype, prefix_attributes); ;
+ break;}
+case 279:
+#line 1524 "objc-parse.y"
+{ if (yyvsp[-2].ttype == error_mark_node)
+ yyval.ttype = yyvsp[-2].ttype;
+ else
+ yyval.ttype = chainon (yyvsp[0].ttype, yyvsp[-2].ttype); ;
+ break;}
+case 280:
+#line 1529 "objc-parse.y"
+{ yyval.ttype = error_mark_node; ;
+ break;}
+case 281:
+#line 1535 "objc-parse.y"
+{ yyval.ttype = build_enumerator (yyvsp[0].ttype, NULL_TREE); ;
+ break;}
+case 282:
+#line 1537 "objc-parse.y"
+{ yyval.ttype = build_enumerator (yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 283:
+#line 1542 "objc-parse.y"
+{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ;
+ break;}
+case 284:
+#line 1544 "objc-parse.y"
+{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ;
+ break;}
+case 285:
+#line 1549 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 287:
+#line 1555 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ;
+ break;}
+case 288:
+#line 1557 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 289:
+#line 1562 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 290:
+#line 1564 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 291:
+#line 1569 "objc-parse.y"
+{ yyval.ttype = yyvsp[-1].ttype; ;
+ break;}
+case 292:
+#line 1572 "objc-parse.y"
+{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
+ break;}
+case 293:
+#line 1574 "objc-parse.y"
+{ yyval.ttype = make_pointer_declarator (yyvsp[0].ttype, NULL_TREE); ;
+ break;}
+case 294:
+#line 1576 "objc-parse.y"
+{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ;
+ break;}
+case 295:
+#line 1578 "objc-parse.y"
+{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 296:
+#line 1580 "objc-parse.y"
+{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ;
+ break;}
+case 297:
+#line 1582 "objc-parse.y"
+{ yyval.ttype = build_nt (CALL_EXPR, NULL_TREE, yyvsp[0].ttype, NULL_TREE); ;
+ break;}
+case 298:
+#line 1584 "objc-parse.y"
+{ yyval.ttype = build_nt (ARRAY_REF, NULL_TREE, yyvsp[-1].ttype); ;
+ break;}
+case 299:
+#line 1586 "objc-parse.y"
+{ yyval.ttype = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); ;
+ break;}
+case 300:
+#line 1597 "objc-parse.y"
+{
+ if (pedantic && yyvsp[0].ends_in_label)
+ pedwarn ("ANSI C forbids label at end of compound statement");
+ ;
+ break;}
+case 302:
+#line 1606 "objc-parse.y"
+{ yyval.ends_in_label = yyvsp[0].ends_in_label; ;
+ break;}
+case 303:
+#line 1608 "objc-parse.y"
+{ yyval.ends_in_label = 0; ;
+ break;}
+case 307:
+#line 1620 "objc-parse.y"
+{ emit_line_note (input_filename, lineno);
+ pushlevel (0);
+ clear_last_expr ();
+ push_momentary ();
+ expand_start_bindings (0);
+ if (objc_method_context)
+ add_objc_decls ();
+ ;
+ break;}
+case 309:
+#line 1635 "objc-parse.y"
+{ if (pedantic)
+ pedwarn ("ANSI C forbids label declarations"); ;
+ break;}
+case 312:
+#line 1646 "objc-parse.y"
+{ tree link;
+ for (link = yyvsp[-1].ttype; link; link = TREE_CHAIN (link))
+ {
+ tree label = shadow_label (TREE_VALUE (link));
+ C_DECLARED_LABEL_FLAG (label) = 1;
+ declare_nonlocal_label (label);
+ }
+ ;
+ break;}
+case 313:
+#line 1660 "objc-parse.y"
+{;
+ break;}
+case 315:
+#line 1664 "objc-parse.y"
+{ compstmt_count++; ;
+ break;}
+case 316:
+#line 1667 "objc-parse.y"
+{ yyval.ttype = convert (void_type_node, integer_zero_node); ;
+ break;}
+case 317:
+#line 1669 "objc-parse.y"
+{ emit_line_note (input_filename, lineno);
+ expand_end_bindings (getdecls (), 1, 0);
+ yyval.ttype = poplevel (1, 1, 0);
+ if (yychar == CONSTANT || yychar == STRING)
+ pop_momentary_nofree ();
+ else
+ pop_momentary (); ;
+ break;}
+case 318:
+#line 1677 "objc-parse.y"
+{ emit_line_note (input_filename, lineno);
+ expand_end_bindings (getdecls (), kept_level_p (), 0);
+ yyval.ttype = poplevel (kept_level_p (), 0, 0);
+ if (yychar == CONSTANT || yychar == STRING)
+ pop_momentary_nofree ();
+ else
+ pop_momentary (); ;
+ break;}
+case 319:
+#line 1685 "objc-parse.y"
+{ emit_line_note (input_filename, lineno);
+ expand_end_bindings (getdecls (), kept_level_p (), 0);
+ yyval.ttype = poplevel (kept_level_p (), 0, 0);
+ if (yychar == CONSTANT || yychar == STRING)
+ pop_momentary_nofree ();
+ else
+ pop_momentary (); ;
+ break;}
+case 322:
+#line 1705 "objc-parse.y"
+{ emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno);
+ c_expand_start_cond (truthvalue_conversion (yyvsp[-1].ttype), 0,
+ compstmt_count);
+ yyval.itype = stmt_count;
+ if_stmt_file = yyvsp[-5].filename;
+ if_stmt_line = yyvsp[-4].lineno;
+ position_after_white_space (); ;
+ break;}
+case 323:
+#line 1719 "objc-parse.y"
+{ stmt_count++;
+ compstmt_count++;
+ emit_line_note (yyvsp[-2].filename, yyvsp[-1].lineno);
+ /* See comment in `while' alternative, above. */
+ emit_nop ();
+ expand_start_loop_continue_elsewhere (1);
+ position_after_white_space (); ;
+ break;}
+case 324:
+#line 1727 "objc-parse.y"
+{ expand_loop_continue_here (); ;
+ break;}
+case 325:
+#line 1731 "objc-parse.y"
+{ yyval.filename = input_filename; ;
+ break;}
+case 326:
+#line 1735 "objc-parse.y"
+{ yyval.lineno = lineno; ;
+ break;}
+case 327:
+#line 1740 "objc-parse.y"
+{ ;
+ break;}
+case 328:
+#line 1745 "objc-parse.y"
+{ ;
+ break;}
+case 329:
+#line 1750 "objc-parse.y"
+{ yyval.ends_in_label = yyvsp[0].ends_in_label; ;
+ break;}
+case 330:
+#line 1755 "objc-parse.y"
+{ yyval.ends_in_label = 0; ;
+ break;}
+case 331:
+#line 1757 "objc-parse.y"
+{ yyval.ends_in_label = 1; ;
+ break;}
+case 332:
+#line 1763 "objc-parse.y"
+{ stmt_count++; ;
+ break;}
+case 334:
+#line 1766 "objc-parse.y"
+{ stmt_count++;
+ emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno);
+/* It appears that this should not be done--that a non-lvalue array
+ shouldn't get an error if the value isn't used.
+ Section 3.2.2.1 says that an array lvalue gets converted to a pointer
+ if it appears as a top-level expression,
+ but says nothing about non-lvalue arrays. */
+#if 0
+ /* Call default_conversion to get an error
+ on referring to a register array if pedantic. */
+ if (TREE_CODE (TREE_TYPE (yyvsp[-1].ttype)) == ARRAY_TYPE
+ || TREE_CODE (TREE_TYPE (yyvsp[-1].ttype)) == FUNCTION_TYPE)
+ yyvsp[-1].ttype = default_conversion (yyvsp[-1].ttype);
+#endif
+ iterator_expand (yyvsp[-1].ttype);
+ clear_momentary (); ;
+ break;}
+case 335:
+#line 1783 "objc-parse.y"
+{ c_expand_start_else ();
+ yyvsp[-1].itype = stmt_count;
+ position_after_white_space (); ;
+ break;}
+case 336:
+#line 1787 "objc-parse.y"
+{ c_expand_end_cond ();
+ if (extra_warnings && stmt_count == yyvsp[-3].itype)
+ warning ("empty body in an else-statement"); ;
+ break;}
+case 337:
+#line 1791 "objc-parse.y"
+{ c_expand_end_cond ();
+ /* This warning is here instead of in simple_if, because we
+ do not want a warning if an empty if is followed by an
+ else statement. Increment stmt_count so we don't
+ give a second error if this is a nested `if'. */
+ if (extra_warnings && stmt_count++ == yyvsp[0].itype)
+ warning_with_file_and_line (if_stmt_file, if_stmt_line,
+ "empty body in an if-statement"); ;
+ break;}
+case 338:
+#line 1803 "objc-parse.y"
+{ c_expand_end_cond (); ;
+ break;}
+case 339:
+#line 1805 "objc-parse.y"
+{ stmt_count++;
+ emit_line_note (yyvsp[-2].filename, yyvsp[-1].lineno);
+ /* The emit_nop used to come before emit_line_note,
+ but that made the nop seem like part of the preceding line.
+ And that was confusing when the preceding line was
+ inside of an if statement and was not really executed.
+ I think it ought to work to put the nop after the line number.
+ We will see. --rms, July 15, 1991. */
+ emit_nop (); ;
+ break;}
+case 340:
+#line 1815 "objc-parse.y"
+{ /* Don't start the loop till we have succeeded
+ in parsing the end test. This is to make sure
+ that we end every loop we start. */
+ expand_start_loop (1);
+ emit_line_note (input_filename, lineno);
+ expand_exit_loop_if_false (NULL_PTR,
+ truthvalue_conversion (yyvsp[-1].ttype));
+ position_after_white_space (); ;
+ break;}
+case 341:
+#line 1824 "objc-parse.y"
+{ expand_end_loop (); ;
+ break;}
+case 342:
+#line 1827 "objc-parse.y"
+{ emit_line_note (input_filename, lineno);
+ expand_exit_loop_if_false (NULL_PTR,
+ truthvalue_conversion (yyvsp[-2].ttype));
+ expand_end_loop ();
+ clear_momentary (); ;
+ break;}
+case 343:
+#line 1834 "objc-parse.y"
+{ expand_end_loop ();
+ clear_momentary (); ;
+ break;}
+case 344:
+#line 1838 "objc-parse.y"
+{ stmt_count++;
+ emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno);
+ /* See comment in `while' alternative, above. */
+ emit_nop ();
+ if (yyvsp[-1].ttype) c_expand_expr_stmt (yyvsp[-1].ttype);
+ /* Next step is to call expand_start_loop_continue_elsewhere,
+ but wait till after we parse the entire for (...).
+ Otherwise, invalid input might cause us to call that
+ fn without calling expand_end_loop. */
+ ;
+ break;}
+case 345:
+#line 1850 "objc-parse.y"
+{ yyvsp[0].lineno = lineno;
+ yyval.filename = input_filename; ;
+ break;}
+case 346:
+#line 1853 "objc-parse.y"
+{
+ /* Start the loop. Doing this after parsing
+ all the expressions ensures we will end the loop. */
+ expand_start_loop_continue_elsewhere (1);
+ /* Emit the end-test, with a line number. */
+ emit_line_note (yyvsp[-2].filename, yyvsp[-3].lineno);
+ if (yyvsp[-4].ttype)
+ expand_exit_loop_if_false (NULL_PTR,
+ truthvalue_conversion (yyvsp[-4].ttype));
+ /* Don't let the tree nodes for $9 be discarded by
+ clear_momentary during the parsing of the next stmt. */
+ push_momentary ();
+ yyvsp[-3].lineno = lineno;
+ yyvsp[-2].filename = input_filename;
+ position_after_white_space (); ;
+ break;}
+case 347:
+#line 1869 "objc-parse.y"
+{ /* Emit the increment expression, with a line number. */
+ emit_line_note (yyvsp[-4].filename, yyvsp[-5].lineno);
+ expand_loop_continue_here ();
+ if (yyvsp[-3].ttype)
+ c_expand_expr_stmt (yyvsp[-3].ttype);
+ if (yychar == CONSTANT || yychar == STRING)
+ pop_momentary_nofree ();
+ else
+ pop_momentary ();
+ expand_end_loop (); ;
+ break;}
+case 348:
+#line 1880 "objc-parse.y"
+{ stmt_count++;
+ emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno);
+ c_expand_start_case (yyvsp[-1].ttype);
+ /* Don't let the tree nodes for $3 be discarded by
+ clear_momentary during the parsing of the next stmt. */
+ push_momentary ();
+ position_after_white_space (); ;
+ break;}
+case 349:
+#line 1888 "objc-parse.y"
+{ expand_end_case (yyvsp[-3].ttype);
+ if (yychar == CONSTANT || yychar == STRING)
+ pop_momentary_nofree ();
+ else
+ pop_momentary (); ;
+ break;}
+case 350:
+#line 1894 "objc-parse.y"
+{ stmt_count++;
+ emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno);
+ if ( ! expand_exit_something ())
+ error ("break statement not within loop or switch"); ;
+ break;}
+case 351:
+#line 1899 "objc-parse.y"
+{ stmt_count++;
+ emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno);
+ if (! expand_continue_loop (NULL_PTR))
+ error ("continue statement not within a loop"); ;
+ break;}
+case 352:
+#line 1904 "objc-parse.y"
+{ stmt_count++;
+ emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno);
+ c_expand_return (NULL_TREE); ;
+ break;}
+case 353:
+#line 1908 "objc-parse.y"
+{ stmt_count++;
+ emit_line_note (yyvsp[-4].filename, yyvsp[-3].lineno);
+ c_expand_return (yyvsp[-1].ttype); ;
+ break;}
+case 354:
+#line 1912 "objc-parse.y"
+{ stmt_count++;
+ emit_line_note (yyvsp[-7].filename, yyvsp[-6].lineno);
+ STRIP_NOPS (yyvsp[-2].ttype);
+ if ((TREE_CODE (yyvsp[-2].ttype) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (yyvsp[-2].ttype, 0)) == STRING_CST)
+ || TREE_CODE (yyvsp[-2].ttype) == STRING_CST)
+ expand_asm (yyvsp[-2].ttype);
+ else
+ error ("argument of `asm' is not a constant string"); ;
+ break;}
+case 355:
+#line 1923 "objc-parse.y"
+{ stmt_count++;
+ emit_line_note (yyvsp[-9].filename, yyvsp[-8].lineno);
+ c_expand_asm_operands (yyvsp[-4].ttype, yyvsp[-2].ttype, NULL_TREE, NULL_TREE,
+ yyvsp[-6].ttype == ridpointers[(int)RID_VOLATILE],
+ input_filename, lineno); ;
+ break;}
+case 356:
+#line 1930 "objc-parse.y"
+{ stmt_count++;
+ emit_line_note (yyvsp[-11].filename, yyvsp[-10].lineno);
+ c_expand_asm_operands (yyvsp[-6].ttype, yyvsp[-4].ttype, yyvsp[-2].ttype, NULL_TREE,
+ yyvsp[-8].ttype == ridpointers[(int)RID_VOLATILE],
+ input_filename, lineno); ;
+ break;}
+case 357:
+#line 1938 "objc-parse.y"
+{ stmt_count++;
+ emit_line_note (yyvsp[-13].filename, yyvsp[-12].lineno);
+ c_expand_asm_operands (yyvsp[-8].ttype, yyvsp[-6].ttype, yyvsp[-4].ttype, yyvsp[-2].ttype,
+ yyvsp[-10].ttype == ridpointers[(int)RID_VOLATILE],
+ input_filename, lineno); ;
+ break;}
+case 358:
+#line 1944 "objc-parse.y"
+{ tree decl;
+ stmt_count++;
+ emit_line_note (yyvsp[-4].filename, yyvsp[-3].lineno);
+ decl = lookup_label (yyvsp[-1].ttype);
+ if (decl != 0)
+ {
+ TREE_USED (decl) = 1;
+ expand_goto (decl);
+ }
+ ;
+ break;}
+case 359:
+#line 1955 "objc-parse.y"
+{ if (pedantic)
+ pedwarn ("ANSI C forbids `goto *expr;'");
+ stmt_count++;
+ emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno);
+ expand_computed_goto (convert (ptr_type_node, yyvsp[-1].ttype)); ;
+ break;}
+case 362:
+#line 1970 "objc-parse.y"
+{
+ /* The value returned by this action is */
+ /* 1 if everything is OK */
+ /* 0 in case of error or already bound iterator */
+
+ yyval.itype = 0;
+ if (TREE_CODE (yyvsp[-1].ttype) != VAR_DECL)
+ error ("invalid `for (ITERATOR)' syntax");
+ else if (! ITERATOR_P (yyvsp[-1].ttype))
+ error ("`%s' is not an iterator",
+ IDENTIFIER_POINTER (DECL_NAME (yyvsp[-1].ttype)));
+ else if (ITERATOR_BOUND_P (yyvsp[-1].ttype))
+ error ("`for (%s)' inside expansion of same iterator",
+ IDENTIFIER_POINTER (DECL_NAME (yyvsp[-1].ttype)));
+ else
+ {
+ yyval.itype = 1;
+ iterator_for_loop_start (yyvsp[-1].ttype);
+ }
+ ;
+ break;}
+case 363:
+#line 1991 "objc-parse.y"
+{
+ if (yyvsp[-1].itype)
+ iterator_for_loop_end (yyvsp[-3].ttype);
+ ;
+ break;}
+case 364:
+#line 2026 "objc-parse.y"
+{ register tree value = check_case_value (yyvsp[-1].ttype);
+ register tree label
+ = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+
+ stmt_count++;
+
+ if (value != error_mark_node)
+ {
+ tree duplicate;
+ int success = pushcase (value, convert_and_check,
+ label, &duplicate);
+ if (success == 1)
+ error ("case label not within a switch statement");
+ else if (success == 2)
+ {
+ error ("duplicate case value");
+ error_with_decl (duplicate, "this is the first entry for that value");
+ }
+ else if (success == 3)
+ warning ("case value out of range");
+ else if (success == 5)
+ error ("case label within scope of cleanup or variable array");
+ }
+ position_after_white_space (); ;
+ break;}
+case 365:
+#line 2051 "objc-parse.y"
+{ register tree value1 = check_case_value (yyvsp[-3].ttype);
+ register tree value2 = check_case_value (yyvsp[-1].ttype);
+ register tree label
+ = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+
+ if (pedantic)
+ pedwarn ("ANSI C forbids case ranges");
+ stmt_count++;
+
+ if (value1 != error_mark_node && value2 != error_mark_node)
+ {
+ tree duplicate;
+ int success = pushcase_range (value1, value2,
+ convert_and_check, label,
+ &duplicate);
+ if (success == 1)
+ error ("case label not within a switch statement");
+ else if (success == 2)
+ {
+ error ("duplicate case value");
+ error_with_decl (duplicate, "this is the first entry for that value");
+ }
+ else if (success == 3)
+ warning ("case value out of range");
+ else if (success == 4)
+ warning ("empty case range");
+ else if (success == 5)
+ error ("case label within scope of cleanup or variable array");
+ }
+ position_after_white_space (); ;
+ break;}
+case 366:
+#line 2082 "objc-parse.y"
+{
+ tree duplicate;
+ register tree label
+ = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+ int success = pushcase (NULL_TREE, 0, label, &duplicate);
+ stmt_count++;
+ if (success == 1)
+ error ("default label not within a switch statement");
+ else if (success == 2)
+ {
+ error ("multiple default labels in one switch");
+ error_with_decl (duplicate, "this is the first default label");
+ }
+ position_after_white_space (); ;
+ break;}
+case 367:
+#line 2097 "objc-parse.y"
+{ tree label = define_label (input_filename, lineno, yyvsp[-1].ttype);
+ stmt_count++;
+ emit_nop ();
+ if (label)
+ expand_label (label);
+ position_after_white_space (); ;
+ break;}
+case 368:
+#line 2109 "objc-parse.y"
+{ emit_line_note (input_filename, lineno);
+ yyval.ttype = NULL_TREE; ;
+ break;}
+case 369:
+#line 2112 "objc-parse.y"
+{ emit_line_note (input_filename, lineno); ;
+ break;}
+case 370:
+#line 2117 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 372:
+#line 2124 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 375:
+#line 2131 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 376:
+#line 2136 "objc-parse.y"
+{ yyval.ttype = build_tree_list (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
+ break;}
+case 377:
+#line 2141 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, combine_strings (yyvsp[0].ttype), NULL_TREE); ;
+ break;}
+case 378:
+#line 2143 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, combine_strings (yyvsp[0].ttype), yyvsp[-2].ttype); ;
+ break;}
+case 379:
+#line 2149 "objc-parse.y"
+{ pushlevel (0);
+ clear_parm_order ();
+ declare_parm_level (0); ;
+ break;}
+case 380:
+#line 2153 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype;
+ parmlist_tags_warning ();
+ poplevel (0, 0, 0); ;
+ break;}
+case 382:
+#line 2161 "objc-parse.y"
+{ tree parm;
+ if (pedantic)
+ pedwarn ("ANSI C forbids forward parameter declarations");
+ /* Mark the forward decls as such. */
+ for (parm = getdecls (); parm; parm = TREE_CHAIN (parm))
+ TREE_ASM_WRITTEN (parm) = 1;
+ clear_parm_order (); ;
+ break;}
+case 383:
+#line 2169 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype; ;
+ break;}
+case 384:
+#line 2171 "objc-parse.y"
+{ yyval.ttype = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); ;
+ break;}
+case 385:
+#line 2177 "objc-parse.y"
+{ yyval.ttype = get_parm_info (0); ;
+ break;}
+case 386:
+#line 2179 "objc-parse.y"
+{ yyval.ttype = get_parm_info (0);
+ /* Gcc used to allow this as an extension. However, it does
+ not work for all targets, and thus has been disabled.
+ Also, since func (...) and func () are indistinguishable,
+ it caused problems with the code in expand_builtin which
+ tries to verify that BUILT_IN_NEXT_ARG is being used
+ correctly. */
+ error ("ANSI C requires a named argument before `...'");
+ ;
+ break;}
+case 387:
+#line 2189 "objc-parse.y"
+{ yyval.ttype = get_parm_info (1); ;
+ break;}
+case 388:
+#line 2191 "objc-parse.y"
+{ yyval.ttype = get_parm_info (0); ;
+ break;}
+case 389:
+#line 2196 "objc-parse.y"
+{ push_parm_decl (yyvsp[0].ttype); ;
+ break;}
+case 390:
+#line 2198 "objc-parse.y"
+{ push_parm_decl (yyvsp[0].ttype); ;
+ break;}
+case 391:
+#line 2205 "objc-parse.y"
+{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
+ yyvsp[-1].ttype),
+ build_tree_list (prefix_attributes,
+ yyvsp[0].ttype));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 392:
+#line 2214 "objc-parse.y"
+{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
+ yyvsp[-1].ttype),
+ build_tree_list (prefix_attributes,
+ yyvsp[0].ttype));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 393:
+#line 2223 "objc-parse.y"
+{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
+ yyvsp[-1].ttype),
+ build_tree_list (prefix_attributes,
+ yyvsp[0].ttype));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 394:
+#line 2232 "objc-parse.y"
+{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
+ yyvsp[-1].ttype),
+ build_tree_list (prefix_attributes,
+ yyvsp[0].ttype));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 395:
+#line 2242 "objc-parse.y"
+{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
+ yyvsp[-1].ttype),
+ build_tree_list (prefix_attributes,
+ yyvsp[0].ttype));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 396:
+#line 2256 "objc-parse.y"
+{ pushlevel (0);
+ clear_parm_order ();
+ declare_parm_level (1); ;
+ break;}
+case 397:
+#line 2260 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype;
+ parmlist_tags_warning ();
+ poplevel (0, 0, 0); ;
+ break;}
+case 399:
+#line 2268 "objc-parse.y"
+{ tree t;
+ for (t = yyvsp[-1].ttype; t; t = TREE_CHAIN (t))
+ if (TREE_VALUE (t) == NULL_TREE)
+ error ("`...' in old-style identifier list");
+ yyval.ttype = tree_cons (NULL_TREE, NULL_TREE, yyvsp[-1].ttype); ;
+ break;}
+case 400:
+#line 2278 "objc-parse.y"
+{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ;
+ break;}
+case 401:
+#line 2280 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ;
+ break;}
+case 402:
+#line 2286 "objc-parse.y"
+{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ;
+ break;}
+case 403:
+#line 2288 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ;
+ break;}
+case 404:
+#line 2293 "objc-parse.y"
+{ yyval.itype = pedantic;
+ pedantic = 0; ;
+ break;}
+case 410:
+#line 2306 "objc-parse.y"
+{
+ if (objc_implementation_context)
+ {
+ finish_class (objc_implementation_context);
+ objc_ivar_chain = NULL_TREE;
+ objc_implementation_context = NULL_TREE;
+ }
+ else
+ warning ("`@end' must appear in an implementation context");
+ ;
+ break;}
+case 411:
+#line 2321 "objc-parse.y"
+{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ;
+ break;}
+case 412:
+#line 2323 "objc-parse.y"
+{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ;
+ break;}
+case 413:
+#line 2328 "objc-parse.y"
+{
+ objc_declare_class (yyvsp[-1].ttype);
+ ;
+ break;}
+case 414:
+#line 2334 "objc-parse.y"
+{
+ objc_declare_alias (yyvsp[-2].ttype, yyvsp[-1].ttype);
+ ;
+ break;}
+case 415:
+#line 2340 "objc-parse.y"
+{
+ objc_interface_context = objc_ivar_context
+ = start_class (CLASS_INTERFACE_TYPE, yyvsp[-2].ttype, NULL_TREE, yyvsp[-1].ttype);
+ objc_public_flag = 0;
+ ;
+ break;}
+case 416:
+#line 2346 "objc-parse.y"
+{
+ continue_class (objc_interface_context);
+ ;
+ break;}
+case 417:
+#line 2351 "objc-parse.y"
+{
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ ;
+ break;}
+case 418:
+#line 2357 "objc-parse.y"
+{
+ objc_interface_context
+ = start_class (CLASS_INTERFACE_TYPE, yyvsp[-1].ttype, NULL_TREE, yyvsp[0].ttype);
+ continue_class (objc_interface_context);
+ ;
+ break;}
+case 419:
+#line 2364 "objc-parse.y"
+{
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ ;
+ break;}
+case 420:
+#line 2370 "objc-parse.y"
+{
+ objc_interface_context = objc_ivar_context
+ = start_class (CLASS_INTERFACE_TYPE, yyvsp[-4].ttype, yyvsp[-2].ttype, yyvsp[-1].ttype);
+ objc_public_flag = 0;
+ ;
+ break;}
+case 421:
+#line 2376 "objc-parse.y"
+{
+ continue_class (objc_interface_context);
+ ;
+ break;}
+case 422:
+#line 2381 "objc-parse.y"
+{
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ ;
+ break;}
+case 423:
+#line 2387 "objc-parse.y"
+{
+ objc_interface_context
+ = start_class (CLASS_INTERFACE_TYPE, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype);
+ continue_class (objc_interface_context);
+ ;
+ break;}
+case 424:
+#line 2394 "objc-parse.y"
+{
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ ;
+ break;}
+case 425:
+#line 2400 "objc-parse.y"
+{
+ objc_implementation_context = objc_ivar_context
+ = start_class (CLASS_IMPLEMENTATION_TYPE, yyvsp[-1].ttype, NULL_TREE, NULL_TREE);
+ objc_public_flag = 0;
+ ;
+ break;}
+case 426:
+#line 2406 "objc-parse.y"
+{
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ ;
+ break;}
+case 427:
+#line 2412 "objc-parse.y"
+{
+ objc_implementation_context
+ = start_class (CLASS_IMPLEMENTATION_TYPE, yyvsp[0].ttype, NULL_TREE, NULL_TREE);
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ ;
+ break;}
+case 428:
+#line 2420 "objc-parse.y"
+{
+ objc_implementation_context = objc_ivar_context
+ = start_class (CLASS_IMPLEMENTATION_TYPE, yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE);
+ objc_public_flag = 0;
+ ;
+ break;}
+case 429:
+#line 2426 "objc-parse.y"
+{
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ ;
+ break;}
+case 430:
+#line 2432 "objc-parse.y"
+{
+ objc_implementation_context
+ = start_class (CLASS_IMPLEMENTATION_TYPE, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE);
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ ;
+ break;}
+case 431:
+#line 2440 "objc-parse.y"
+{
+ objc_interface_context
+ = start_class (CATEGORY_INTERFACE_TYPE, yyvsp[-4].ttype, yyvsp[-2].ttype, yyvsp[0].ttype);
+ continue_class (objc_interface_context);
+ ;
+ break;}
+case 432:
+#line 2447 "objc-parse.y"
+{
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ ;
+ break;}
+case 433:
+#line 2453 "objc-parse.y"
+{
+ objc_implementation_context
+ = start_class (CATEGORY_IMPLEMENTATION_TYPE, yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE);
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ ;
+ break;}
+case 434:
+#line 2463 "objc-parse.y"
+{
+ remember_protocol_qualifiers ();
+ objc_interface_context
+ = start_protocol(PROTOCOL_INTERFACE_TYPE, yyvsp[-1].ttype, yyvsp[0].ttype);
+ ;
+ break;}
+case 435:
+#line 2469 "objc-parse.y"
+{
+ forget_protocol_qualifiers();
+ finish_protocol(objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ ;
+ break;}
+case 436:
+#line 2478 "objc-parse.y"
+{
+ yyval.ttype = NULL_TREE;
+ ;
+ break;}
+case 438:
+#line 2486 "objc-parse.y"
+{
+ if (yyvsp[-2].code == LT_EXPR && yyvsp[0].code == GT_EXPR)
+ yyval.ttype = yyvsp[-1].ttype;
+ else
+ YYERROR1;
+ ;
+ break;}
+case 441:
+#line 2500 "objc-parse.y"
+{ objc_public_flag = 2; ;
+ break;}
+case 442:
+#line 2501 "objc-parse.y"
+{ objc_public_flag = 0; ;
+ break;}
+case 443:
+#line 2502 "objc-parse.y"
+{ objc_public_flag = 1; ;
+ break;}
+case 444:
+#line 2507 "objc-parse.y"
+{
+ yyval.ttype = NULL_TREE;
+ ;
+ break;}
+case 446:
+#line 2512 "objc-parse.y"
+{
+ if (pedantic)
+ pedwarn ("extra semicolon in struct or union specified");
+ ;
+ break;}
+case 447:
+#line 2530 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype;
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-1].itype); ;
+ break;}
+case 448:
+#line 2536 "objc-parse.y"
+{ yyval.ttype = yyvsp[0].ttype;
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-1].itype); ;
+ break;}
+case 449:
+#line 2542 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 450:
+#line 2547 "objc-parse.y"
+{ yyval.ttype = NULL_TREE; ;
+ break;}
+case 453:
+#line 2554 "objc-parse.y"
+{
+ yyval.ttype = add_instance_variable (objc_ivar_context,
+ objc_public_flag,
+ yyvsp[0].ttype, current_declspecs,
+ NULL_TREE);
+ ;
+ break;}
+case 454:
+#line 2561 "objc-parse.y"
+{
+ yyval.ttype = add_instance_variable (objc_ivar_context,
+ objc_public_flag,
+ yyvsp[-2].ttype, current_declspecs, yyvsp[0].ttype);
+ ;
+ break;}
+case 455:
+#line 2567 "objc-parse.y"
+{
+ yyval.ttype = add_instance_variable (objc_ivar_context,
+ objc_public_flag,
+ NULL_TREE,
+ current_declspecs, yyvsp[0].ttype);
+ ;
+ break;}
+case 456:
+#line 2577 "objc-parse.y"
+{
+ remember_protocol_qualifiers ();
+ if (objc_implementation_context)
+ objc_inherit_code = CLASS_METHOD_DECL;
+ else
+ fatal ("method definition not in class context");
+ ;
+ break;}
+case 457:
+#line 2585 "objc-parse.y"
+{
+ forget_protocol_qualifiers ();
+ add_class_method (objc_implementation_context, yyvsp[0].ttype);
+ start_method_def (yyvsp[0].ttype);
+ objc_method_context = yyvsp[0].ttype;
+ ;
+ break;}
+case 458:
+#line 2592 "objc-parse.y"
+{
+ continue_method_def ();
+ ;
+ break;}
+case 459:
+#line 2596 "objc-parse.y"
+{
+ finish_method_def ();
+ objc_method_context = NULL_TREE;
+ ;
+ break;}
+case 460:
+#line 2602 "objc-parse.y"
+{
+ remember_protocol_qualifiers ();
+ if (objc_implementation_context)
+ objc_inherit_code = INSTANCE_METHOD_DECL;
+ else
+ fatal ("method definition not in class context");
+ ;
+ break;}
+case 461:
+#line 2610 "objc-parse.y"
+{
+ forget_protocol_qualifiers ();
+ add_instance_method (objc_implementation_context, yyvsp[0].ttype);
+ start_method_def (yyvsp[0].ttype);
+ objc_method_context = yyvsp[0].ttype;
+ ;
+ break;}
+case 462:
+#line 2617 "objc-parse.y"
+{
+ continue_method_def ();
+ ;
+ break;}
+case 463:
+#line 2621 "objc-parse.y"
+{
+ finish_method_def ();
+ objc_method_context = NULL_TREE;
+ ;
+ break;}
+case 465:
+#line 2633 "objc-parse.y"
+{yyval.ttype = NULL_TREE; ;
+ break;}
+case 470:
+#line 2640 "objc-parse.y"
+{yyval.ttype = NULL_TREE; ;
+ break;}
+case 474:
+#line 2650 "objc-parse.y"
+{
+ objc_inherit_code = CLASS_METHOD_DECL;
+ ;
+ break;}
+case 475:
+#line 2654 "objc-parse.y"
+{
+ add_class_method (objc_interface_context, yyvsp[0].ttype);
+ ;
+ break;}
+case 477:
+#line 2660 "objc-parse.y"
+{
+ objc_inherit_code = INSTANCE_METHOD_DECL;
+ ;
+ break;}
+case 478:
+#line 2664 "objc-parse.y"
+{
+ add_instance_method (objc_interface_context, yyvsp[0].ttype);
+ ;
+ break;}
+case 480:
+#line 2672 "objc-parse.y"
+{
+ yyval.ttype = build_method_decl (objc_inherit_code, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE);
+ ;
+ break;}
+case 481:
+#line 2677 "objc-parse.y"
+{
+ yyval.ttype = build_method_decl (objc_inherit_code, NULL_TREE, yyvsp[0].ttype, NULL_TREE);
+ ;
+ break;}
+case 482:
+#line 2682 "objc-parse.y"
+{
+ yyval.ttype = build_method_decl (objc_inherit_code, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype);
+ ;
+ break;}
+case 483:
+#line 2687 "objc-parse.y"
+{
+ yyval.ttype = build_method_decl (objc_inherit_code, NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype);
+ ;
+ break;}
+case 492:
+#line 2717 "objc-parse.y"
+{ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary (yyvsp[-2].itype); ;
+ break;}
+case 493:
+#line 2722 "objc-parse.y"
+{ shadow_tag (yyvsp[-1].ttype); ;
+ break;}
+case 494:
+#line 2724 "objc-parse.y"
+{ pedwarn ("empty declaration"); ;
+ break;}
+case 495:
+#line 2729 "objc-parse.y"
+{ push_parm_decl (yyvsp[0].ttype); ;
+ break;}
+case 496:
+#line 2731 "objc-parse.y"
+{ push_parm_decl (yyvsp[0].ttype); ;
+ break;}
+case 497:
+#line 2739 "objc-parse.y"
+{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
+ yyvsp[-1].ttype),
+ build_tree_list (prefix_attributes,
+ yyvsp[0].ttype)); ;
+ break;}
+case 498:
+#line 2744 "objc-parse.y"
+{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
+ yyvsp[-1].ttype),
+ build_tree_list (prefix_attributes,
+ yyvsp[0].ttype)); ;
+ break;}
+case 499:
+#line 2749 "objc-parse.y"
+{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
+ yyvsp[-1].ttype),
+ build_tree_list (prefix_attributes,
+ yyvsp[0].ttype)); ;
+ break;}
+case 500:
+#line 2757 "objc-parse.y"
+{
+ yyval.ttype = NULL_TREE;
+ ;
+ break;}
+case 501:
+#line 2761 "objc-parse.y"
+{
+ /* oh what a kludge! */
+ yyval.ttype = (tree)1;
+ ;
+ break;}
+case 502:
+#line 2766 "objc-parse.y"
+{
+ pushlevel (0);
+ ;
+ break;}
+case 503:
+#line 2770 "objc-parse.y"
+{
+ /* returns a tree list node generated by get_parm_info */
+ yyval.ttype = yyvsp[0].ttype;
+ poplevel (0, 0, 0);
+ ;
+ break;}
+case 506:
+#line 2785 "objc-parse.y"
+{
+ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype);
+ ;
+ break;}
+case 511:
+#line 2798 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 512:
+#line 2799 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 513:
+#line 2800 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 514:
+#line 2801 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 515:
+#line 2802 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 516:
+#line 2803 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 517:
+#line 2804 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 518:
+#line 2805 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 519:
+#line 2806 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 520:
+#line 2807 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 521:
+#line 2808 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 522:
+#line 2809 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 523:
+#line 2810 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 524:
+#line 2811 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 525:
+#line 2812 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 526:
+#line 2813 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 527:
+#line 2814 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 528:
+#line 2815 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 529:
+#line 2816 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 532:
+#line 2822 "objc-parse.y"
+{
+ yyval.ttype = build_keyword_decl (yyvsp[-5].ttype, yyvsp[-2].ttype, yyvsp[0].ttype);
+ ;
+ break;}
+case 533:
+#line 2827 "objc-parse.y"
+{
+ yyval.ttype = build_keyword_decl (yyvsp[-2].ttype, NULL_TREE, yyvsp[0].ttype);
+ ;
+ break;}
+case 534:
+#line 2832 "objc-parse.y"
+{
+ yyval.ttype = build_keyword_decl (NULL_TREE, yyvsp[-2].ttype, yyvsp[0].ttype);
+ ;
+ break;}
+case 535:
+#line 2837 "objc-parse.y"
+{
+ yyval.ttype = build_keyword_decl (NULL_TREE, NULL_TREE, yyvsp[0].ttype);
+ ;
+ break;}
+case 539:
+#line 2850 "objc-parse.y"
+{
+ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype);
+ ;
+ break;}
+case 540:
+#line 2858 "objc-parse.y"
+{
+ if (TREE_CHAIN (yyvsp[0].ttype) == NULL_TREE)
+ /* just return the expr., remove a level of indirection */
+ yyval.ttype = TREE_VALUE (yyvsp[0].ttype);
+ else
+ /* we have a comma expr., we will collapse later */
+ yyval.ttype = yyvsp[0].ttype;
+ ;
+ break;}
+case 541:
+#line 2870 "objc-parse.y"
+{
+ yyval.ttype = build_tree_list (yyvsp[-2].ttype, yyvsp[0].ttype);
+ ;
+ break;}
+case 542:
+#line 2874 "objc-parse.y"
+{
+ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype);
+ ;
+ break;}
+case 544:
+#line 2882 "objc-parse.y"
+{
+ yyval.ttype = get_class_reference (yyvsp[0].ttype);
+ ;
+ break;}
+case 545:
+#line 2889 "objc-parse.y"
+{ objc_receiver_context = 1; ;
+ break;}
+case 546:
+#line 2891 "objc-parse.y"
+{ objc_receiver_context = 0; ;
+ break;}
+case 547:
+#line 2893 "objc-parse.y"
+{
+ yyval.ttype = build_tree_list (yyvsp[-3].ttype, yyvsp[-1].ttype);
+ ;
+ break;}
+case 551:
+#line 2906 "objc-parse.y"
+{
+ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype);
+ ;
+ break;}
+case 552:
+#line 2913 "objc-parse.y"
+{
+ yyval.ttype = build_tree_list (yyvsp[-1].ttype, NULL_TREE);
+ ;
+ break;}
+case 553:
+#line 2917 "objc-parse.y"
+{
+ yyval.ttype = build_tree_list (NULL_TREE, NULL_TREE);
+ ;
+ break;}
+case 554:
+#line 2924 "objc-parse.y"
+{
+ yyval.ttype = yyvsp[-1].ttype;
+ ;
+ break;}
+case 555:
+#line 2931 "objc-parse.y"
+{
+ yyval.ttype = yyvsp[-1].ttype;
+ ;
+ break;}
+case 556:
+#line 2940 "objc-parse.y"
+{
+ yyval.ttype = groktypename (yyvsp[-1].ttype);
+ ;
+ break;}
+}
+ /* the action file gets copied in in place of this dollarsign */
+#line 487 "/usr/local/share/bison.simple"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+ yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+ yylsp++;
+ if (yylen == 0)
+ {
+ yylsp->first_line = yylloc.first_line;
+ yylsp->first_column = yylloc.first_column;
+ yylsp->last_line = (yylsp-1)->last_line;
+ yylsp->last_column = (yylsp-1)->last_column;
+ yylsp->text = 0;
+ }
+ else
+ {
+ yylsp->last_line = (yylsp+yylen-1)->last_line;
+ yylsp->last_column = (yylsp+yylen-1)->last_column;
+ }
+#endif
+
+ /* Now "shift" the result of the reduction.
+ Determine what state that goes to,
+ based on the state we popped back to
+ and the rule number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ goto yynewstate;
+
+yyerrlab: /* here on detecting error */
+
+ if (! yyerrstatus)
+ /* If not already recovering from an error, report this error. */
+ {
+ ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (yyn > YYFLAG && yyn < YYLAST)
+ {
+ int size = 0;
+ char *msg;
+ int x, count;
+
+ count = 0;
+ /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ size += strlen(yytname[x]) + 15, count++;
+ msg = (char *) malloc(size + 15);
+ if (msg != 0)
+ {
+ strcpy(msg, "parse error");
+
+ if (count < 5)
+ {
+ count = 0;
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ {
+ strcat(msg, count == 0 ? ", expecting `" : " or `");
+ strcat(msg, yytname[x]);
+ strcat(msg, "'");
+ count++;
+ }
+ }
+ yyerror(msg);
+ free(msg);
+ }
+ else
+ yyerror ("parse error; also virtual memory exceeded");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror("parse error");
+ }
+
+ goto yyerrlab1;
+yyerrlab1: /* here on error raised explicitly by an action */
+
+ if (yyerrstatus == 3)
+ {
+ /* if just tried and failed to reuse lookahead token after an error, discard it. */
+
+ /* return failure if at end of input */
+ if (yychar == YYEOF)
+ YYABORT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token
+ after shifting the error token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this */
+
+ goto yyerrhandle;
+
+yyerrdefault: /* current state does not do anything special for the error token. */
+
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+ yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
+ if (yyn) goto yydefault;
+#endif
+
+yyerrpop: /* pop the current state because it cannot handle the error token */
+
+ if (yyssp == yyss) YYABORT;
+ yyvsp--;
+ yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+ yylsp--;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "Error: state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+yyerrhandle:
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yyerrdefault;
+
+ yyn += YYTERROR;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+ goto yyerrdefault;
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrpop;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrpop;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting error token, ");
+#endif
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ yystate = yyn;
+ goto yynewstate;
+}
+#line 2945 "objc-parse.y"
+
diff --git a/gnu/usr.bin/gcc/objc/objc-parse.y b/gnu/usr.bin/gcc/objc/objc-parse.y
new file mode 100644
index 00000000000..4dc0bcf95ca
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/objc-parse.y
@@ -0,0 +1,2945 @@
+/*WARNING: This file is automatically generated!*/
+/* YACC parser for C syntax and for Objective C. -*-c-*-
+ Copyright (C) 1987, 88, 89, 92-6, 1997 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 grammar of C and that of Objective C.
+ ifobjc ... end ifobjc conditionals contain code for Objective C only.
+ ifc ... end ifc conditionals contain code for C only.
+ Sed commands in Makefile.in are used to convert this file into
+ c-parse.y and into objc-parse.y. */
+
+/* To whomever it may concern: I have heard that such a thing was once
+ written by AT&T, but I have never seen it. */
+
+%expect 66
+
+%{
+#include "config.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <setjmp.h>
+
+#include "tree.h"
+#include "input.h"
+#include "c-lex.h"
+#include "c-tree.h"
+#include "flags.h"
+
+#ifdef MULTIBYTE_CHARS
+#include <stdlib.h>
+#include <locale.h>
+#endif
+
+#include "objc-act.h"
+
+/* Since parsers are distinct for each language, put the language string
+ definition here. */
+char *language_string = "GNU Obj-C";
+
+#ifndef errno
+extern int errno;
+#endif
+
+void yyerror ();
+
+/* Like YYERROR but do call yyerror. */
+#define YYERROR1 { yyerror ("syntax error"); YYERROR; }
+
+/* Cause the `yydebug' variable to be defined. */
+#define YYDEBUG 1
+%}
+
+%start program
+
+%union {long itype; tree ttype; enum tree_code code;
+ char *filename; int lineno; int ends_in_label; }
+
+/* All identifiers that are not reserved words
+ and are not declared typedefs in the current block */
+%token IDENTIFIER
+
+/* All identifiers that are declared typedefs in the current block.
+ In some contexts, they are treated just like IDENTIFIER,
+ but they can also serve as typespecs in declarations. */
+%token TYPENAME
+
+/* Reserved words that specify storage class.
+ yylval contains an IDENTIFIER_NODE which indicates which one. */
+%token SCSPEC
+
+/* Reserved words that specify type.
+ yylval contains an IDENTIFIER_NODE which indicates which one. */
+%token TYPESPEC
+
+/* Reserved words that qualify type: "const" or "volatile".
+ yylval contains an IDENTIFIER_NODE which indicates which one. */
+%token TYPE_QUAL
+
+/* Character or numeric constants.
+ yylval is the node for the constant. */
+%token CONSTANT
+
+/* String constants in raw form.
+ yylval is a STRING_CST node. */
+%token STRING
+
+/* "...", used for functions with variable arglists. */
+%token ELLIPSIS
+
+/* the reserved words */
+/* SCO include files test "ASM", so use something else. */
+%token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
+%token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF
+%token ATTRIBUTE EXTENSION LABEL
+%token REALPART IMAGPART
+
+/* Add precedence rules to solve dangling else s/r conflict */
+%nonassoc IF
+%nonassoc ELSE
+
+/* Define the operator tokens and their precedences.
+ The value is an integer because, if used, it is the tree code
+ to use in the expression made from the operator. */
+
+%right <code> ASSIGN '='
+%right <code> '?' ':'
+%left <code> OROR
+%left <code> ANDAND
+%left <code> '|'
+%left <code> '^'
+%left <code> '&'
+%left <code> EQCOMPARE
+%left <code> ARITHCOMPARE
+%left <code> LSHIFT RSHIFT
+%left <code> '+' '-'
+%left <code> '*' '/' '%'
+%right <code> UNARY PLUSPLUS MINUSMINUS
+%left HYPERUNARY
+%left <code> POINTSAT '.' '(' '['
+
+/* The Objective-C keywords. These are included in C and in
+ Objective C, so that the token codes are the same in both. */
+%token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
+%token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS
+
+/* Objective-C string constants in raw form.
+ yylval is an OBJC_STRING_CST node. */
+%token OBJC_STRING
+
+
+%type <code> unop
+
+%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist
+%type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
+%type <ttype> typed_declspecs reserved_declspecs
+%type <ttype> typed_typespecs reserved_typespecquals
+%type <ttype> declmods typespec typespecqual_reserved
+%type <ttype> typed_declspecs_no_prefix_attr reserved_declspecs_no_prefix_attr
+%type <ttype> declmods_no_prefix_attr
+%type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
+%type <ttype> initdecls notype_initdecls initdcl notype_initdcl
+%type <ttype> init maybeasm
+%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
+%type <ttype> maybe_attribute attributes attribute attribute_list attrib
+%type <ttype> any_word
+
+%type <ttype> compstmt
+
+%type <ttype> declarator
+%type <ttype> notype_declarator after_type_declarator
+%type <ttype> parm_declarator
+
+%type <ttype> structsp component_decl_list component_decl_list2
+%type <ttype> component_decl components component_declarator
+%type <ttype> enumlist enumerator
+%type <ttype> typename absdcl absdcl1 type_quals
+%type <ttype> xexpr parms parm identifiers
+
+%type <ttype> parmlist parmlist_1 parmlist_2
+%type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1
+%type <ttype> identifiers_or_typenames
+
+%type <itype> setspecs
+
+%type <ends_in_label> lineno_stmt_or_label lineno_stmt_or_labels stmt_or_label
+
+%type <filename> save_filename
+%type <lineno> save_lineno
+
+/* the Objective-C nonterminals */
+
+%type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator
+%type <ttype> methoddecl unaryselector keywordselector selector
+%type <ttype> keyworddecl receiver objcmessageexpr messageargs
+%type <ttype> keywordexpr keywordarglist keywordarg
+%type <ttype> myparms myparm optparmlist reservedwords objcselectorexpr
+%type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
+%type <ttype> objc_string non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr
+
+%type <ttype> CLASSNAME OBJC_STRING OBJECTNAME
+
+%{
+/* Number of statements (loosely speaking) and compound statements
+ seen so far. */
+static int stmt_count;
+static int compstmt_count;
+
+/* Input file and line number of the end of the body of last simple_if;
+ used by the stmt-rule immediately after simple_if returns. */
+static char *if_stmt_file;
+static int if_stmt_line;
+
+/* List of types and structure classes of the current declaration. */
+static tree current_declspecs = NULL_TREE;
+static tree prefix_attributes = NULL_TREE;
+
+/* Stack of saved values of current_declspecs and prefix_attributes. */
+static tree declspec_stack;
+
+/* 1 if we explained undeclared var errors. */
+static int undeclared_variable_notice;
+
+/* Objective-C specific information */
+
+tree objc_interface_context;
+tree objc_implementation_context;
+tree objc_method_context;
+tree objc_ivar_chain;
+tree objc_ivar_context;
+enum tree_code objc_inherit_code;
+int objc_receiver_context;
+int objc_public_flag;
+
+
+/* Tell yyparse how to print a token's value, if yydebug is set. */
+
+#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
+extern void yyprint ();
+%}
+
+%%
+program: /* empty */
+ { if (pedantic)
+ pedwarn ("ANSI C forbids an empty source file");
+ finish_file ();
+ }
+ | extdefs
+ {
+ /* In case there were missing closebraces,
+ get us back to the global binding level. */
+ while (! global_bindings_p ())
+ poplevel (0, 0, 0);
+ finish_file ();
+ }
+ ;
+
+/* the reason for the strange actions in this rule
+ is so that notype_initdecls when reached via datadef
+ can find a valid list of type and sc specs in $0. */
+
+extdefs:
+ {$<ttype>$ = NULL_TREE; } extdef
+ | extdefs {$<ttype>$ = NULL_TREE; } extdef
+ ;
+
+extdef:
+ fndef
+ | datadef
+ | objcdef
+ | ASM_KEYWORD '(' expr ')' ';'
+ { STRIP_NOPS ($3);
+ if ((TREE_CODE ($3) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND ($3, 0)) == STRING_CST)
+ || TREE_CODE ($3) == STRING_CST)
+ assemble_asm ($3);
+ else
+ error ("argument of `asm' is not a constant string"); }
+ | extension extdef
+ { pedantic = $<itype>1; }
+ ;
+
+datadef:
+ setspecs notype_initdecls ';'
+ { if (pedantic)
+ error ("ANSI C forbids data definition with no type or storage class");
+ else if (!flag_traditional)
+ warning ("data definition has no type or storage class");
+
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($1); }
+ | declmods setspecs notype_initdecls ';'
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | typed_declspecs setspecs initdecls ';'
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | declmods ';'
+ { pedwarn ("empty declaration"); }
+ | typed_declspecs ';'
+ { shadow_tag ($1); }
+ | error ';'
+ | error '}'
+ | ';'
+ { if (pedantic)
+ pedwarn ("ANSI C does not allow extra `;' outside of a function"); }
+ ;
+
+fndef:
+ typed_declspecs setspecs declarator
+ { if (! start_function (current_declspecs, $3,
+ prefix_attributes, NULL_TREE, 0))
+ YYERROR1;
+ reinit_parse_for_function (); }
+ old_style_parm_decls
+ { store_parm_decls (); }
+ compstmt_or_error
+ { finish_function (0);
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | typed_declspecs setspecs declarator error
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | declmods setspecs notype_declarator
+ { if (! start_function (current_declspecs, $3,
+ prefix_attributes, NULL_TREE, 0))
+ YYERROR1;
+ reinit_parse_for_function (); }
+ old_style_parm_decls
+ { store_parm_decls (); }
+ compstmt_or_error
+ { finish_function (0);
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | declmods setspecs notype_declarator error
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | setspecs notype_declarator
+ { if (! start_function (NULL_TREE, $2,
+ prefix_attributes, NULL_TREE, 0))
+ YYERROR1;
+ reinit_parse_for_function (); }
+ old_style_parm_decls
+ { store_parm_decls (); }
+ compstmt_or_error
+ { finish_function (0);
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($1); }
+ | setspecs notype_declarator error
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($1); }
+ ;
+
+identifier:
+ IDENTIFIER
+ | TYPENAME
+ | OBJECTNAME
+ | CLASSNAME
+ ;
+
+unop: '&'
+ { $$ = ADDR_EXPR; }
+ | '-'
+ { $$ = NEGATE_EXPR; }
+ | '+'
+ { $$ = CONVERT_EXPR; }
+ | PLUSPLUS
+ { $$ = PREINCREMENT_EXPR; }
+ | MINUSMINUS
+ { $$ = PREDECREMENT_EXPR; }
+ | '~'
+ { $$ = BIT_NOT_EXPR; }
+ | '!'
+ { $$ = TRUTH_NOT_EXPR; }
+ ;
+
+expr: nonnull_exprlist
+ { $$ = build_compound_expr ($1); }
+ ;
+
+exprlist:
+ /* empty */
+ { $$ = NULL_TREE; }
+ | nonnull_exprlist
+ ;
+
+nonnull_exprlist:
+ expr_no_commas
+ { $$ = build_tree_list (NULL_TREE, $1); }
+ | nonnull_exprlist ',' expr_no_commas
+ { chainon ($1, build_tree_list (NULL_TREE, $3)); }
+ ;
+
+unary_expr:
+ primary
+ | '*' cast_expr %prec UNARY
+ { $$ = build_indirect_ref ($2, "unary *"); }
+ /* __extension__ turns off -pedantic for following primary. */
+ | extension cast_expr %prec UNARY
+ { $$ = $2;
+ pedantic = $<itype>1; }
+ | unop cast_expr %prec UNARY
+ { $$ = build_unary_op ($1, $2, 0);
+ overflow_warning ($$); }
+ /* Refer to the address of a label as a pointer. */
+ | ANDAND identifier
+ { tree label = lookup_label ($2);
+ if (pedantic)
+ pedwarn ("ANSI C forbids `&&'");
+ if (label == 0)
+ $$ = null_pointer_node;
+ else
+ {
+ TREE_USED (label) = 1;
+ $$ = build1 (ADDR_EXPR, ptr_type_node, label);
+ TREE_CONSTANT ($$) = 1;
+ }
+ }
+/* This seems to be impossible on some machines, so let's turn it off.
+ You can use __builtin_next_arg to find the anonymous stack args.
+ | '&' ELLIPSIS
+ { tree types = TYPE_ARG_TYPES (TREE_TYPE (current_function_decl));
+ $$ = error_mark_node;
+ if (TREE_VALUE (tree_last (types)) == void_type_node)
+ error ("`&...' used in function with fixed number of arguments");
+ else
+ {
+ if (pedantic)
+ pedwarn ("ANSI C forbids `&...'");
+ $$ = tree_last (DECL_ARGUMENTS (current_function_decl));
+ $$ = build_unary_op (ADDR_EXPR, $$, 0);
+ } }
+*/
+ | sizeof unary_expr %prec UNARY
+ { skip_evaluation--;
+ if (TREE_CODE ($2) == COMPONENT_REF
+ && DECL_C_BIT_FIELD (TREE_OPERAND ($2, 1)))
+ error ("`sizeof' applied to a bit-field");
+ $$ = c_sizeof (TREE_TYPE ($2)); }
+ | sizeof '(' typename ')' %prec HYPERUNARY
+ { skip_evaluation--;
+ $$ = c_sizeof (groktypename ($3)); }
+ | alignof unary_expr %prec UNARY
+ { skip_evaluation--;
+ $$ = c_alignof_expr ($2); }
+ | alignof '(' typename ')' %prec HYPERUNARY
+ { skip_evaluation--;
+ $$ = c_alignof (groktypename ($3)); }
+ | REALPART cast_expr %prec UNARY
+ { $$ = build_unary_op (REALPART_EXPR, $2, 0); }
+ | IMAGPART cast_expr %prec UNARY
+ { $$ = build_unary_op (IMAGPART_EXPR, $2, 0); }
+ ;
+
+sizeof:
+ SIZEOF { skip_evaluation++; }
+ ;
+
+alignof:
+ ALIGNOF { skip_evaluation++; }
+ ;
+
+cast_expr:
+ unary_expr
+ | '(' typename ')' cast_expr %prec UNARY
+ { tree type = groktypename ($2);
+ $$ = build_c_cast (type, $4); }
+ | '(' typename ')' '{'
+ { start_init (NULL_TREE, NULL, 0);
+ $2 = groktypename ($2);
+ really_start_incremental_init ($2); }
+ initlist_maybe_comma '}' %prec UNARY
+ { char *name;
+ tree result = pop_init_level (0);
+ tree type = $2;
+ finish_init ();
+
+ if (pedantic)
+ pedwarn ("ANSI C forbids constructor expressions");
+ if (TYPE_NAME (type) != 0)
+ {
+ if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
+ name = IDENTIFIER_POINTER (TYPE_NAME (type));
+ else
+ name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+ }
+ else
+ name = "";
+ $$ = result;
+ if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
+ {
+ int failure = complete_array_type (type, $$, 1);
+ if (failure)
+ abort ();
+ }
+ }
+ ;
+
+expr_no_commas:
+ cast_expr
+ | expr_no_commas '+' expr_no_commas
+ { $$ = parser_build_binary_op ($2, $1, $3); }
+ | expr_no_commas '-' expr_no_commas
+ { $$ = parser_build_binary_op ($2, $1, $3); }
+ | expr_no_commas '*' expr_no_commas
+ { $$ = parser_build_binary_op ($2, $1, $3); }
+ | expr_no_commas '/' expr_no_commas
+ { $$ = parser_build_binary_op ($2, $1, $3); }
+ | expr_no_commas '%' expr_no_commas
+ { $$ = parser_build_binary_op ($2, $1, $3); }
+ | expr_no_commas LSHIFT expr_no_commas
+ { $$ = parser_build_binary_op ($2, $1, $3); }
+ | expr_no_commas RSHIFT expr_no_commas
+ { $$ = parser_build_binary_op ($2, $1, $3); }
+ | expr_no_commas ARITHCOMPARE expr_no_commas
+ { $$ = parser_build_binary_op ($2, $1, $3); }
+ | expr_no_commas EQCOMPARE expr_no_commas
+ { $$ = parser_build_binary_op ($2, $1, $3); }
+ | expr_no_commas '&' expr_no_commas
+ { $$ = parser_build_binary_op ($2, $1, $3); }
+ | expr_no_commas '|' expr_no_commas
+ { $$ = parser_build_binary_op ($2, $1, $3); }
+ | expr_no_commas '^' expr_no_commas
+ { $$ = parser_build_binary_op ($2, $1, $3); }
+ | expr_no_commas ANDAND
+ { $1 = truthvalue_conversion (default_conversion ($1));
+ skip_evaluation += $1 == boolean_false_node; }
+ expr_no_commas
+ { skip_evaluation -= $1 == boolean_false_node;
+ $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $4); }
+ | expr_no_commas OROR
+ { $1 = truthvalue_conversion (default_conversion ($1));
+ skip_evaluation += $1 == boolean_true_node; }
+ expr_no_commas
+ { skip_evaluation -= $1 == boolean_true_node;
+ $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $4); }
+ | expr_no_commas '?'
+ { $1 = truthvalue_conversion (default_conversion ($1));
+ skip_evaluation += $1 == boolean_false_node; }
+ expr ':'
+ { skip_evaluation += (($1 == boolean_true_node)
+ - ($1 == boolean_false_node)); }
+ expr_no_commas
+ { skip_evaluation -= $1 == boolean_true_node;
+ $$ = build_conditional_expr ($1, $4, $7); }
+ | expr_no_commas '?'
+ { if (pedantic)
+ pedwarn ("ANSI C forbids omitting the middle term of a ?: expression");
+ /* Make sure first operand is calculated only once. */
+ $<ttype>2 = save_expr ($1);
+ $1 = truthvalue_conversion (default_conversion ($<ttype>2));
+ skip_evaluation += $1 == boolean_true_node; }
+ ':' expr_no_commas
+ { skip_evaluation -= $1 == boolean_true_node;
+ $$ = build_conditional_expr ($1, $<ttype>2, $5); }
+ | expr_no_commas '=' expr_no_commas
+ { $$ = build_modify_expr ($1, NOP_EXPR, $3);
+ C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); }
+ | expr_no_commas ASSIGN expr_no_commas
+ { $$ = build_modify_expr ($1, $2, $3);
+ /* This inhibits warnings in truthvalue_conversion. */
+ C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); }
+ ;
+
+primary:
+ IDENTIFIER
+ {
+ $$ = lastiddecl;
+ if (!$$ || $$ == error_mark_node)
+ {
+ if (yychar == YYEMPTY)
+ yychar = YYLEX;
+ if (yychar == '(')
+ {
+ tree decl;
+
+ if (objc_receiver_context
+ && ! (objc_receiver_context
+ && strcmp (IDENTIFIER_POINTER ($1), "super")))
+ /* we have a message to super */
+ $$ = get_super_receiver ();
+ else if (objc_method_context
+ && (decl = is_ivar (objc_ivar_chain, $1)))
+ {
+ if (is_private (decl))
+ $$ = error_mark_node;
+ else
+ $$ = build_ivar_reference ($1);
+ }
+ else
+ {
+ /* Ordinary implicit function declaration. */
+ $$ = implicitly_declare ($1);
+ assemble_external ($$);
+ TREE_USED ($$) = 1;
+ }
+ }
+ else if (current_function_decl == 0)
+ {
+ error ("`%s' undeclared here (not in a function)",
+ IDENTIFIER_POINTER ($1));
+ $$ = error_mark_node;
+ }
+ else
+ {
+ tree decl;
+
+ if (objc_receiver_context
+ && ! strcmp (IDENTIFIER_POINTER ($1), "super"))
+ /* we have a message to super */
+ $$ = get_super_receiver ();
+ else if (objc_method_context
+ && (decl = is_ivar (objc_ivar_chain, $1)))
+ {
+ if (is_private (decl))
+ $$ = error_mark_node;
+ else
+ $$ = build_ivar_reference ($1);
+ }
+ else
+ {
+ if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node
+ || IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl)
+ {
+ error ("`%s' undeclared (first use this function)",
+ IDENTIFIER_POINTER ($1));
+
+ if (! undeclared_variable_notice)
+ {
+ error ("(Each undeclared identifier is reported only once");
+ error ("for each function it appears in.)");
+ undeclared_variable_notice = 1;
+ }
+ }
+ $$ = error_mark_node;
+ /* Prevent repeated error messages. */
+ IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node;
+ IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl;
+ }
+ }
+ }
+ else if (TREE_TYPE ($$) == error_mark_node)
+ $$ = error_mark_node;
+ else if (C_DECL_ANTICIPATED ($$))
+ {
+ /* The first time we see a build-in function used,
+ if it has not been declared. */
+ C_DECL_ANTICIPATED ($$) = 0;
+ if (yychar == YYEMPTY)
+ yychar = YYLEX;
+ if (yychar == '(')
+ {
+ /* Omit the implicit declaration we
+ would ordinarily do, so we don't lose
+ the actual built in type.
+ But print a diagnostic for the mismatch. */
+ if (objc_method_context
+ && is_ivar (objc_ivar_chain, $1))
+ error ("Instance variable `%s' implicitly declared as function",
+ IDENTIFIER_POINTER (DECL_NAME ($$)));
+ else
+ if (TREE_CODE ($$) != FUNCTION_DECL)
+ error ("`%s' implicitly declared as function",
+ IDENTIFIER_POINTER (DECL_NAME ($$)));
+ else if ((TYPE_MODE (TREE_TYPE (TREE_TYPE ($$)))
+ != TYPE_MODE (integer_type_node))
+ && (TREE_TYPE (TREE_TYPE ($$))
+ != void_type_node))
+ pedwarn ("type mismatch in implicit declaration for built-in function `%s'",
+ IDENTIFIER_POINTER (DECL_NAME ($$)));
+ /* If it really returns void, change that to int. */
+ if (TREE_TYPE (TREE_TYPE ($$)) == void_type_node)
+ TREE_TYPE ($$)
+ = build_function_type (integer_type_node,
+ TYPE_ARG_TYPES (TREE_TYPE ($$)));
+ }
+ else
+ pedwarn ("built-in function `%s' used without declaration",
+ IDENTIFIER_POINTER (DECL_NAME ($$)));
+
+ /* Do what we would ordinarily do when a fn is used. */
+ assemble_external ($$);
+ TREE_USED ($$) = 1;
+ }
+ else
+ {
+ assemble_external ($$);
+ TREE_USED ($$) = 1;
+ /* we have a definition - still check if iVariable */
+
+ if (!objc_receiver_context
+ || (objc_receiver_context
+ && strcmp (IDENTIFIER_POINTER ($1), "super")))
+ {
+ tree decl;
+
+ if (objc_method_context
+ && (decl = is_ivar (objc_ivar_chain, $1)))
+ {
+ if (IDENTIFIER_LOCAL_VALUE ($1))
+ warning ("local declaration of `%s' hides instance variable",
+ IDENTIFIER_POINTER ($1));
+ else
+ {
+ if (is_private (decl))
+ $$ = error_mark_node;
+ else
+ $$ = build_ivar_reference ($1);
+ }
+ }
+ }
+ else /* we have a message to super */
+ $$ = get_super_receiver ();
+ }
+
+ if (TREE_CODE ($$) == CONST_DECL)
+ {
+ $$ = DECL_INITIAL ($$);
+ /* This is to prevent an enum whose value is 0
+ from being considered a null pointer constant. */
+ $$ = build1 (NOP_EXPR, TREE_TYPE ($$), $$);
+ TREE_CONSTANT ($$) = 1;
+ }
+ }
+ | CONSTANT
+ | string
+ { $$ = combine_strings ($1); }
+ | '(' expr ')'
+ { char class = TREE_CODE_CLASS (TREE_CODE ($2));
+ if (class == 'e' || class == '1'
+ || class == '2' || class == '<')
+ C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK);
+ $$ = $2; }
+ | '(' error ')'
+ { $$ = error_mark_node; }
+ | '('
+ { if (current_function_decl == 0)
+ {
+ error ("braced-group within expression allowed only inside a function");
+ YYERROR;
+ }
+ /* We must force a BLOCK for this level
+ so that, if it is not expanded later,
+ there is a way to turn off the entire subtree of blocks
+ that are contained in it. */
+ keep_next_level ();
+ push_iterator_stack ();
+ push_label_level ();
+ $<ttype>$ = expand_start_stmt_expr (); }
+ compstmt ')'
+ { tree rtl_exp;
+ if (pedantic)
+ pedwarn ("ANSI C forbids braced-groups within expressions");
+ pop_iterator_stack ();
+ pop_label_level ();
+ rtl_exp = expand_end_stmt_expr ($<ttype>2);
+ /* The statements have side effects, so the group does. */
+ TREE_SIDE_EFFECTS (rtl_exp) = 1;
+
+ if (TREE_CODE ($3) == BLOCK)
+ {
+ /* Make a BIND_EXPR for the BLOCK already made. */
+ $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp),
+ NULL_TREE, rtl_exp, $3);
+ /* Remove the block from the tree at this point.
+ It gets put back at the proper place
+ when the BIND_EXPR is expanded. */
+ delete_block ($3);
+ }
+ else
+ $$ = $3;
+ }
+ | primary '(' exprlist ')' %prec '.'
+ { $$ = build_function_call ($1, $3); }
+ | primary '[' expr ']' %prec '.'
+ { $$ = build_array_ref ($1, $3); }
+ | primary '.' identifier
+ {
+ if (doing_objc_thang)
+ {
+ if (is_public ($1, $3))
+ $$ = build_component_ref ($1, $3);
+ else
+ $$ = error_mark_node;
+ }
+ else
+ $$ = build_component_ref ($1, $3);
+ }
+ | primary POINTSAT identifier
+ {
+ tree expr = build_indirect_ref ($1, "->");
+
+ if (doing_objc_thang)
+ {
+ if (is_public (expr, $3))
+ $$ = build_component_ref (expr, $3);
+ else
+ $$ = error_mark_node;
+ }
+ else
+ $$ = build_component_ref (expr, $3);
+ }
+ | primary PLUSPLUS
+ { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }
+ | primary MINUSMINUS
+ { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }
+ | objcmessageexpr
+ { $$ = build_message_expr ($1); }
+ | objcselectorexpr
+ { $$ = build_selector_expr ($1); }
+ | objcprotocolexpr
+ { $$ = build_protocol_expr ($1); }
+ | objcencodeexpr
+ { $$ = build_encode_expr ($1); }
+ | objc_string
+ { $$ = build_objc_string_object ($1); }
+ ;
+
+/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */
+string:
+ STRING
+ | string STRING
+ { $$ = chainon ($1, $2); }
+ ;
+
+/* Produces an OBJC_STRING_CST with perhaps more OBJC_STRING_CSTs chained
+ onto it. */
+objc_string:
+ OBJC_STRING
+ | objc_string OBJC_STRING
+ { $$ = chainon ($1, $2); }
+ ;
+
+old_style_parm_decls:
+ /* empty */
+ | datadecls
+ | datadecls ELLIPSIS
+ /* ... is used here to indicate a varargs function. */
+ { c_mark_varargs ();
+ if (pedantic)
+ pedwarn ("ANSI C does not permit use of `varargs.h'"); }
+ ;
+
+/* The following are analogous to lineno_decl, decls and decl
+ except that they do not allow nested functions.
+ They are used for old-style parm decls. */
+lineno_datadecl:
+ save_filename save_lineno datadecl
+ { }
+ ;
+
+datadecls:
+ lineno_datadecl
+ | errstmt
+ | datadecls lineno_datadecl
+ | lineno_datadecl errstmt
+ ;
+
+/* We don't allow prefix attributes here because they cause reduce/reduce
+ conflicts: we can't know whether we're parsing a function decl with
+ attribute suffix, or function defn with attribute prefix on first old
+ style parm. */
+datadecl:
+ typed_declspecs_no_prefix_attr setspecs initdecls ';'
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | declmods_no_prefix_attr setspecs notype_initdecls ';'
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | typed_declspecs_no_prefix_attr ';'
+ { shadow_tag_warned ($1, 1);
+ pedwarn ("empty declaration"); }
+ | declmods_no_prefix_attr ';'
+ { pedwarn ("empty declaration"); }
+ ;
+
+/* This combination which saves a lineno before a decl
+ is the normal thing to use, rather than decl itself.
+ This is to avoid shift/reduce conflicts in contexts
+ where statement labels are allowed. */
+lineno_decl:
+ save_filename save_lineno decl
+ { }
+ ;
+
+decls:
+ lineno_decl
+ | errstmt
+ | decls lineno_decl
+ | lineno_decl errstmt
+ ;
+
+/* records the type and storage class specs to use for processing
+ the declarators that follow.
+ Maintains a stack of outer-level values of current_declspecs,
+ for the sake of parm declarations nested in function declarators. */
+setspecs: /* empty */
+ { $$ = suspend_momentary ();
+ pending_xref_error ();
+ declspec_stack = tree_cons (prefix_attributes,
+ current_declspecs,
+ declspec_stack);
+ split_specs_attrs ($<ttype>0,
+ &current_declspecs, &prefix_attributes); }
+ ;
+
+/* ??? Yuck. See after_type_declarator. */
+setattrs: /* empty */
+ { prefix_attributes = chainon (prefix_attributes, $<ttype>0); }
+ ;
+
+decl:
+ typed_declspecs setspecs initdecls ';'
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | declmods setspecs notype_initdecls ';'
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | typed_declspecs setspecs nested_function
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | declmods setspecs notype_nested_function
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | typed_declspecs ';'
+ { shadow_tag ($1); }
+ | declmods ';'
+ { pedwarn ("empty declaration"); }
+ | extension decl
+ { pedantic = $<itype>1; }
+ ;
+
+/* Declspecs which contain at least one type specifier or typedef name.
+ (Just `const' or `volatile' is not enough.)
+ A typedef'd name following these is taken as a name to be declared.
+ Declspecs have a non-NULL TREE_VALUE, attributes do not. */
+
+typed_declspecs:
+ typespec reserved_declspecs
+ { $$ = tree_cons (NULL_TREE, $1, $2); }
+ | declmods typespec reserved_declspecs
+ { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
+ ;
+
+reserved_declspecs: /* empty */
+ { $$ = NULL_TREE; }
+ | reserved_declspecs typespecqual_reserved
+ { $$ = tree_cons (NULL_TREE, $2, $1); }
+ | reserved_declspecs SCSPEC
+ { if (extra_warnings)
+ warning ("`%s' is not at beginning of declaration",
+ IDENTIFIER_POINTER ($2));
+ $$ = tree_cons (NULL_TREE, $2, $1); }
+ | reserved_declspecs attributes
+ { $$ = tree_cons ($2, NULL_TREE, $1); }
+ ;
+
+typed_declspecs_no_prefix_attr:
+ typespec reserved_declspecs_no_prefix_attr
+ { $$ = tree_cons (NULL_TREE, $1, $2); }
+ | declmods_no_prefix_attr typespec reserved_declspecs_no_prefix_attr
+ { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
+ ;
+
+reserved_declspecs_no_prefix_attr:
+ /* empty */
+ { $$ = NULL_TREE; }
+ | reserved_declspecs_no_prefix_attr typespecqual_reserved
+ { $$ = tree_cons (NULL_TREE, $2, $1); }
+ | reserved_declspecs_no_prefix_attr SCSPEC
+ { if (extra_warnings)
+ warning ("`%s' is not at beginning of declaration",
+ IDENTIFIER_POINTER ($2));
+ $$ = tree_cons (NULL_TREE, $2, $1); }
+ ;
+
+/* List of just storage classes, type modifiers, and prefix attributes.
+ A declaration can start with just this, but then it cannot be used
+ to redeclare a typedef-name.
+ Declspecs have a non-NULL TREE_VALUE, attributes do not. */
+
+declmods:
+ declmods_no_prefix_attr
+ { $$ = $1; }
+ | attributes
+ { $$ = tree_cons ($1, NULL_TREE, NULL_TREE); }
+ | declmods declmods_no_prefix_attr
+ { $$ = chainon ($2, $1); }
+ | declmods attributes
+ { $$ = tree_cons ($2, NULL_TREE, $1); }
+ ;
+
+declmods_no_prefix_attr:
+ TYPE_QUAL
+ { $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
+ TREE_STATIC ($$) = 1; }
+ | SCSPEC
+ { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
+ | declmods_no_prefix_attr TYPE_QUAL
+ { $$ = tree_cons (NULL_TREE, $2, $1);
+ TREE_STATIC ($$) = 1; }
+ | declmods_no_prefix_attr SCSPEC
+ { if (extra_warnings && TREE_STATIC ($1))
+ warning ("`%s' is not at beginning of declaration",
+ IDENTIFIER_POINTER ($2));
+ $$ = tree_cons (NULL_TREE, $2, $1);
+ TREE_STATIC ($$) = TREE_STATIC ($1); }
+ ;
+
+
+/* Used instead of declspecs where storage classes are not allowed
+ (that is, for typenames and structure components).
+ Don't accept a typedef-name if anything but a modifier precedes it. */
+
+typed_typespecs:
+ typespec reserved_typespecquals
+ { $$ = tree_cons (NULL_TREE, $1, $2); }
+ | nonempty_type_quals typespec reserved_typespecquals
+ { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
+ ;
+
+reserved_typespecquals: /* empty */
+ { $$ = NULL_TREE; }
+ | reserved_typespecquals typespecqual_reserved
+ { $$ = tree_cons (NULL_TREE, $2, $1); }
+ ;
+
+/* A typespec (but not a type qualifier).
+ Once we have seen one of these in a declaration,
+ if a typedef name appears then it is being redeclared. */
+
+typespec: TYPESPEC
+ | structsp
+ | TYPENAME
+ { /* For a typedef name, record the meaning, not the name.
+ In case of `foo foo, bar;'. */
+ $$ = lookup_name ($1); }
+ | CLASSNAME protocolrefs
+ { $$ = get_static_reference ($1, $2); }
+ | OBJECTNAME protocolrefs
+ { $$ = get_object_reference ($2); }
+
+/* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>"
+ - nisse@lysator.liu.se */
+ | non_empty_protocolrefs
+ { $$ = get_object_reference ($1); }
+ | TYPEOF '(' expr ')'
+ { $$ = TREE_TYPE ($3); }
+ | TYPEOF '(' typename ')'
+ { $$ = groktypename ($3); }
+ ;
+
+/* A typespec that is a reserved word, or a type qualifier. */
+
+typespecqual_reserved: TYPESPEC
+ | TYPE_QUAL
+ | structsp
+ ;
+
+initdecls:
+ initdcl
+ | initdecls ',' initdcl
+ ;
+
+notype_initdecls:
+ notype_initdcl
+ | notype_initdecls ',' initdcl
+ ;
+
+maybeasm:
+ /* empty */
+ { $$ = NULL_TREE; }
+ | ASM_KEYWORD '(' string ')'
+ { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
+ $$ = $3;
+ }
+ ;
+
+initdcl:
+ declarator maybeasm maybe_attribute '='
+ { $<ttype>$ = start_decl ($1, current_declspecs, 1,
+ $3, prefix_attributes);
+ start_init ($<ttype>$, $2, global_bindings_p ()); }
+ init
+/* Note how the declaration of the variable is in effect while its init is parsed! */
+ { finish_init ();
+ finish_decl ($<ttype>5, $6, $2); }
+ | declarator maybeasm maybe_attribute
+ { tree d = start_decl ($1, current_declspecs, 0,
+ $3, prefix_attributes);
+ finish_decl (d, NULL_TREE, $2);
+ }
+ ;
+
+notype_initdcl:
+ notype_declarator maybeasm maybe_attribute '='
+ { $<ttype>$ = start_decl ($1, current_declspecs, 1,
+ $3, prefix_attributes);
+ start_init ($<ttype>$, $2, global_bindings_p ()); }
+ init
+/* Note how the declaration of the variable is in effect while its init is parsed! */
+ { finish_init ();
+ decl_attributes ($<ttype>5, $3, prefix_attributes);
+ finish_decl ($<ttype>5, $6, $2); }
+ | notype_declarator maybeasm maybe_attribute
+ { tree d = start_decl ($1, current_declspecs, 0,
+ $3, prefix_attributes);
+ finish_decl (d, NULL_TREE, $2); }
+ ;
+/* the * rules are dummies to accept the Apollo extended syntax
+ so that the header files compile. */
+maybe_attribute:
+ /* empty */
+ { $$ = NULL_TREE; }
+ | attributes
+ { $$ = $1; }
+ ;
+
+attributes:
+ attribute
+ { $$ = $1; }
+ | attributes attribute
+ { $$ = chainon ($1, $2); }
+ ;
+
+attribute:
+ ATTRIBUTE '(' '(' attribute_list ')' ')'
+ { $$ = $4; }
+ ;
+
+attribute_list:
+ attrib
+ { $$ = $1; }
+ | attribute_list ',' attrib
+ { $$ = chainon ($1, $3); }
+ ;
+
+attrib:
+ /* empty */
+ { $$ = NULL_TREE; }
+ | any_word
+ { $$ = build_tree_list ($1, NULL_TREE); }
+ | any_word '(' IDENTIFIER ')'
+ { $$ = build_tree_list ($1, build_tree_list (NULL_TREE, $3)); }
+ | any_word '(' IDENTIFIER ',' nonnull_exprlist ')'
+ { $$ = build_tree_list ($1, tree_cons (NULL_TREE, $3, $5)); }
+ | any_word '(' exprlist ')'
+ { $$ = build_tree_list ($1, $3); }
+ ;
+
+/* This still leaves out most reserved keywords,
+ shouldn't we include them? */
+
+any_word:
+ identifier
+ | SCSPEC
+ | TYPESPEC
+ | TYPE_QUAL
+ ;
+
+/* Initializers. `init' is the entry point. */
+
+init:
+ expr_no_commas
+ | '{'
+ { really_start_incremental_init (NULL_TREE);
+ /* Note that the call to clear_momentary
+ is in process_init_element. */
+ push_momentary (); }
+ initlist_maybe_comma '}'
+ { $$ = pop_init_level (0);
+ if ($$ == error_mark_node
+ && ! (yychar == STRING || yychar == CONSTANT))
+ pop_momentary ();
+ else
+ pop_momentary_nofree (); }
+
+ | error
+ { $$ = error_mark_node; }
+ ;
+
+/* `initlist_maybe_comma' is the guts of an initializer in braces. */
+initlist_maybe_comma:
+ /* empty */
+ { if (pedantic)
+ pedwarn ("ANSI C forbids empty initializer braces"); }
+ | initlist1 maybecomma
+ ;
+
+initlist1:
+ initelt
+ | initlist1 ',' initelt
+ ;
+
+/* `initelt' is a single element of an initializer.
+ It may use braces. */
+initelt:
+ expr_no_commas
+ { process_init_element ($1); }
+ | '{'
+ { push_init_level (0); }
+ initlist_maybe_comma '}'
+ { process_init_element (pop_init_level (0)); }
+ | error
+ /* These are for labeled elements. The syntax for an array element
+ initializer conflicts with the syntax for an Objective-C message,
+ so don't include these productions in the Objective-C grammar. */
+ | identifier ':'
+ { set_init_label ($1); }
+ initelt
+ | '.' identifier '='
+ { set_init_label ($2); }
+ initelt
+ ;
+
+nested_function:
+ declarator
+ { push_c_function_context ();
+ if (! start_function (current_declspecs, $1,
+ prefix_attributes, NULL_TREE, 1))
+ {
+ pop_c_function_context ();
+ YYERROR1;
+ }
+ reinit_parse_for_function (); }
+ old_style_parm_decls
+ { store_parm_decls (); }
+/* This used to use compstmt_or_error.
+ That caused a bug with input `f(g) int g {}',
+ where the use of YYERROR1 above caused an error
+ which then was handled by compstmt_or_error.
+ There followed a repeated execution of that same rule,
+ which called YYERROR1 again, and so on. */
+ compstmt
+ { finish_function (1);
+ pop_c_function_context (); }
+ ;
+
+notype_nested_function:
+ notype_declarator
+ { push_c_function_context ();
+ if (! start_function (current_declspecs, $1,
+ prefix_attributes, NULL_TREE, 1))
+ {
+ pop_c_function_context ();
+ YYERROR1;
+ }
+ reinit_parse_for_function (); }
+ old_style_parm_decls
+ { store_parm_decls (); }
+/* This used to use compstmt_or_error.
+ That caused a bug with input `f(g) int g {}',
+ where the use of YYERROR1 above caused an error
+ which then was handled by compstmt_or_error.
+ There followed a repeated execution of that same rule,
+ which called YYERROR1 again, and so on. */
+ compstmt
+ { finish_function (1);
+ pop_c_function_context (); }
+ ;
+
+/* Any kind of declarator (thus, all declarators allowed
+ after an explicit typespec). */
+
+declarator:
+ after_type_declarator
+ | notype_declarator
+ ;
+
+/* A declarator that is allowed only after an explicit typespec. */
+
+after_type_declarator:
+ '(' after_type_declarator ')'
+ { $$ = $2; }
+ | after_type_declarator '(' parmlist_or_identifiers %prec '.'
+ { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
+/* | after_type_declarator '(' error ')' %prec '.'
+ { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
+ poplevel (0, 0, 0); } */
+ | after_type_declarator '[' expr ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, $1, $3); }
+ | after_type_declarator '[' ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
+ | '*' type_quals after_type_declarator %prec UNARY
+ { $$ = make_pointer_declarator ($2, $3); }
+ /* ??? Yuck. setattrs is a quick hack. We can't use
+ prefix_attributes because $1 only applies to this
+ declarator. We assume setspecs has already been done.
+ setattrs also avoids 5 reduce/reduce conflicts (otherwise multiple
+ attributes could be recognized here or in `attributes'). */
+ | attributes setattrs after_type_declarator
+ { $$ = $3; }
+ | TYPENAME
+ | OBJECTNAME
+ ;
+
+/* Kinds of declarator that can appear in a parameter list
+ in addition to notype_declarator. This is like after_type_declarator
+ but does not allow a typedef name in parentheses as an identifier
+ (because it would conflict with a function with that typedef as arg). */
+
+parm_declarator:
+ parm_declarator '(' parmlist_or_identifiers %prec '.'
+ { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
+/* | parm_declarator '(' error ')' %prec '.'
+ { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
+ poplevel (0, 0, 0); } */
+ | parm_declarator '[' expr ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, $1, $3); }
+ | parm_declarator '[' ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
+ | '*' type_quals parm_declarator %prec UNARY
+ { $$ = make_pointer_declarator ($2, $3); }
+ /* ??? Yuck. setattrs is a quick hack. We can't use
+ prefix_attributes because $1 only applies to this
+ declarator. We assume setspecs has already been done.
+ setattrs also avoids 5 reduce/reduce conflicts (otherwise multiple
+ attributes could be recognized here or in `attributes'). */
+ | attributes setattrs parm_declarator
+ { $$ = $3; }
+ | TYPENAME
+ ;
+
+/* A declarator allowed whether or not there has been
+ an explicit typespec. These cannot redeclare a typedef-name. */
+
+notype_declarator:
+ notype_declarator '(' parmlist_or_identifiers %prec '.'
+ { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
+/* | notype_declarator '(' error ')' %prec '.'
+ { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
+ poplevel (0, 0, 0); } */
+ | '(' notype_declarator ')'
+ { $$ = $2; }
+ | '*' type_quals notype_declarator %prec UNARY
+ { $$ = make_pointer_declarator ($2, $3); }
+ | notype_declarator '[' expr ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, $1, $3); }
+ | notype_declarator '[' ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
+ /* ??? Yuck. setattrs is a quick hack. We can't use
+ prefix_attributes because $1 only applies to this
+ declarator. We assume setspecs has already been done.
+ setattrs also avoids 5 reduce/reduce conflicts (otherwise multiple
+ attributes could be recognized here or in `attributes'). */
+ | attributes setattrs notype_declarator
+ { $$ = $3; }
+ | IDENTIFIER
+ ;
+
+structsp:
+ STRUCT identifier '{'
+ { $$ = start_struct (RECORD_TYPE, $2);
+ /* Start scope of tag before parsing components. */
+ }
+ component_decl_list '}' maybe_attribute
+ { $$ = finish_struct ($<ttype>4, $5, $7); }
+ | STRUCT '{' component_decl_list '}' maybe_attribute
+ { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
+ $3, $5);
+ }
+ | STRUCT identifier
+ { $$ = xref_tag (RECORD_TYPE, $2); }
+ | UNION identifier '{'
+ { $$ = start_struct (UNION_TYPE, $2); }
+ component_decl_list '}' maybe_attribute
+ { $$ = finish_struct ($<ttype>4, $5, $7); }
+ | UNION '{' component_decl_list '}' maybe_attribute
+ { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
+ $3, $5);
+ }
+ | UNION identifier
+ { $$ = xref_tag (UNION_TYPE, $2); }
+ | ENUM identifier '{'
+ { $<itype>3 = suspend_momentary ();
+ $$ = start_enum ($2); }
+ enumlist maybecomma_warn '}' maybe_attribute
+ { $$ = finish_enum ($<ttype>4, nreverse ($5), $8);
+ resume_momentary ($<itype>3); }
+ | ENUM '{'
+ { $<itype>2 = suspend_momentary ();
+ $$ = start_enum (NULL_TREE); }
+ enumlist maybecomma_warn '}' maybe_attribute
+ { $$ = finish_enum ($<ttype>3, nreverse ($4), $7);
+ resume_momentary ($<itype>2); }
+ | ENUM identifier
+ { $$ = xref_tag (ENUMERAL_TYPE, $2); }
+ ;
+
+maybecomma:
+ /* empty */
+ | ','
+ ;
+
+maybecomma_warn:
+ /* empty */
+ | ','
+ { if (pedantic) pedwarn ("comma at end of enumerator list"); }
+ ;
+
+component_decl_list:
+ component_decl_list2
+ { $$ = $1; }
+ | component_decl_list2 component_decl
+ { $$ = chainon ($1, $2);
+ pedwarn ("no semicolon at end of struct or union"); }
+ ;
+
+component_decl_list2: /* empty */
+ { $$ = NULL_TREE; }
+ | component_decl_list2 component_decl ';'
+ { $$ = chainon ($1, $2); }
+ | component_decl_list2 ';'
+ { if (pedantic)
+ pedwarn ("extra semicolon in struct or union specified"); }
+ /* foo(sizeof(struct{ @defs(ClassName)})); */
+ | DEFS '(' CLASSNAME ')'
+ {
+ tree interface = lookup_interface ($3);
+
+ if (interface)
+ $$ = get_class_ivars (interface);
+ else
+ {
+ error ("Cannot find interface declaration for `%s'",
+ IDENTIFIER_POINTER ($3));
+ $$ = NULL_TREE;
+ }
+ }
+ ;
+
+/* There is a shift-reduce conflict here, because `components' may
+ start with a `typename'. It happens that shifting (the default resolution)
+ does the right thing, because it treats the `typename' as part of
+ a `typed_typespecs'.
+
+ It is possible that this same technique would allow the distinction
+ between `notype_initdecls' and `initdecls' to be eliminated.
+ But I am being cautious and not trying it. */
+
+component_decl:
+ typed_typespecs setspecs components
+ { $$ = $3;
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | typed_typespecs
+ { if (pedantic)
+ pedwarn ("ANSI C forbids member declarations with no members");
+ shadow_tag($1);
+ $$ = NULL_TREE; }
+ | nonempty_type_quals setspecs components
+ { $$ = $3;
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | nonempty_type_quals
+ { if (pedantic)
+ pedwarn ("ANSI C forbids member declarations with no members");
+ shadow_tag($1);
+ $$ = NULL_TREE; }
+ | error
+ { $$ = NULL_TREE; }
+ | extension component_decl
+ { $$ = $2;
+ pedantic = $<itype>1; }
+ ;
+
+components:
+ component_declarator
+ | components ',' component_declarator
+ { $$ = chainon ($1, $3); }
+ ;
+
+component_declarator:
+ save_filename save_lineno declarator maybe_attribute
+ { $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
+ decl_attributes ($$, $4, prefix_attributes); }
+ | save_filename save_lineno
+ declarator ':' expr_no_commas maybe_attribute
+ { $$ = grokfield ($1, $2, $3, current_declspecs, $5);
+ decl_attributes ($$, $6, prefix_attributes); }
+ | save_filename save_lineno ':' expr_no_commas maybe_attribute
+ { $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4);
+ decl_attributes ($$, $5, prefix_attributes); }
+ ;
+
+/* We chain the enumerators in reverse order.
+ They are put in forward order where enumlist is used.
+ (The order used to be significant, but no longer is so.
+ However, we still maintain the order, just to be clean.) */
+
+enumlist:
+ enumerator
+ | enumlist ',' enumerator
+ { if ($1 == error_mark_node)
+ $$ = $1;
+ else
+ $$ = chainon ($3, $1); }
+ | error
+ { $$ = error_mark_node; }
+ ;
+
+
+enumerator:
+ identifier
+ { $$ = build_enumerator ($1, NULL_TREE); }
+ | identifier '=' expr_no_commas
+ { $$ = build_enumerator ($1, $3); }
+ ;
+
+typename:
+ typed_typespecs absdcl
+ { $$ = build_tree_list ($1, $2); }
+ | nonempty_type_quals absdcl
+ { $$ = build_tree_list ($1, $2); }
+ ;
+
+absdcl: /* an absolute declarator */
+ /* empty */
+ { $$ = NULL_TREE; }
+ | absdcl1
+ ;
+
+nonempty_type_quals:
+ TYPE_QUAL
+ { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
+ | nonempty_type_quals TYPE_QUAL
+ { $$ = tree_cons (NULL_TREE, $2, $1); }
+ ;
+
+type_quals:
+ /* empty */
+ { $$ = NULL_TREE; }
+ | type_quals TYPE_QUAL
+ { $$ = tree_cons (NULL_TREE, $2, $1); }
+ ;
+
+absdcl1: /* a nonempty absolute declarator */
+ '(' absdcl1 ')'
+ { $$ = $2; }
+ /* `(typedef)1' is `int'. */
+ | '*' type_quals absdcl1 %prec UNARY
+ { $$ = make_pointer_declarator ($2, $3); }
+ | '*' type_quals %prec UNARY
+ { $$ = make_pointer_declarator ($2, NULL_TREE); }
+ | absdcl1 '(' parmlist %prec '.'
+ { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
+ | absdcl1 '[' expr ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, $1, $3); }
+ | absdcl1 '[' ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
+ | '(' parmlist %prec '.'
+ { $$ = build_nt (CALL_EXPR, NULL_TREE, $2, NULL_TREE); }
+ | '[' expr ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); }
+ | '[' ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); }
+ /* ??? It appears we have to support attributes here, however
+ using prefix_attributes is wrong. */
+ ;
+
+/* at least one statement, the first of which parses without error. */
+/* stmts is used only after decls, so an invalid first statement
+ is actually regarded as an invalid decl and part of the decls. */
+
+stmts:
+ lineno_stmt_or_labels
+ {
+ if (pedantic && $1)
+ pedwarn ("ANSI C forbids label at end of compound statement");
+ }
+ ;
+
+lineno_stmt_or_labels:
+ lineno_stmt_or_label
+ | lineno_stmt_or_labels lineno_stmt_or_label
+ { $$ = $2; }
+ | lineno_stmt_or_labels errstmt
+ { $$ = 0; }
+ ;
+
+xstmts:
+ /* empty */
+ | stmts
+ ;
+
+errstmt: error ';'
+ ;
+
+pushlevel: /* empty */
+ { emit_line_note (input_filename, lineno);
+ pushlevel (0);
+ clear_last_expr ();
+ push_momentary ();
+ expand_start_bindings (0);
+ if (objc_method_context)
+ add_objc_decls ();
+ }
+ ;
+
+/* Read zero or more forward-declarations for labels
+ that nested functions can jump to. */
+maybe_label_decls:
+ /* empty */
+ | label_decls
+ { if (pedantic)
+ pedwarn ("ANSI C forbids label declarations"); }
+ ;
+
+label_decls:
+ label_decl
+ | label_decls label_decl
+ ;
+
+label_decl:
+ LABEL identifiers_or_typenames ';'
+ { tree link;
+ for (link = $2; link; link = TREE_CHAIN (link))
+ {
+ tree label = shadow_label (TREE_VALUE (link));
+ C_DECLARED_LABEL_FLAG (label) = 1;
+ declare_nonlocal_label (label);
+ }
+ }
+ ;
+
+/* This is the body of a function definition.
+ It causes syntax errors to ignore to the next openbrace. */
+compstmt_or_error:
+ compstmt
+ {}
+ | error compstmt
+ ;
+
+compstmt_start: '{' { compstmt_count++; }
+
+compstmt: compstmt_start '}'
+ { $$ = convert (void_type_node, integer_zero_node); }
+ | compstmt_start pushlevel maybe_label_decls decls xstmts '}'
+ { emit_line_note (input_filename, lineno);
+ expand_end_bindings (getdecls (), 1, 0);
+ $$ = poplevel (1, 1, 0);
+ if (yychar == CONSTANT || yychar == STRING)
+ pop_momentary_nofree ();
+ else
+ pop_momentary (); }
+ | compstmt_start pushlevel maybe_label_decls error '}'
+ { emit_line_note (input_filename, lineno);
+ expand_end_bindings (getdecls (), kept_level_p (), 0);
+ $$ = poplevel (kept_level_p (), 0, 0);
+ if (yychar == CONSTANT || yychar == STRING)
+ pop_momentary_nofree ();
+ else
+ pop_momentary (); }
+ | compstmt_start pushlevel maybe_label_decls stmts '}'
+ { emit_line_note (input_filename, lineno);
+ expand_end_bindings (getdecls (), kept_level_p (), 0);
+ $$ = poplevel (kept_level_p (), 0, 0);
+ if (yychar == CONSTANT || yychar == STRING)
+ pop_momentary_nofree ();
+ else
+ pop_momentary (); }
+ ;
+
+/* Value is number of statements counted as of the closeparen. */
+simple_if:
+ if_prefix lineno_labeled_stmt
+/* Make sure c_expand_end_cond is run once
+ for each call to c_expand_start_cond.
+ Otherwise a crash is likely. */
+ | if_prefix error
+ ;
+
+if_prefix:
+ IF '(' expr ')'
+ { emit_line_note ($<filename>-1, $<lineno>0);
+ c_expand_start_cond (truthvalue_conversion ($3), 0,
+ compstmt_count);
+ $<itype>$ = stmt_count;
+ if_stmt_file = $<filename>-1;
+ if_stmt_line = $<lineno>0;
+ position_after_white_space (); }
+ ;
+
+/* This is a subroutine of stmt.
+ It is used twice, once for valid DO statements
+ and once for catching errors in parsing the end test. */
+do_stmt_start:
+ DO
+ { stmt_count++;
+ compstmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ /* See comment in `while' alternative, above. */
+ emit_nop ();
+ expand_start_loop_continue_elsewhere (1);
+ position_after_white_space (); }
+ lineno_labeled_stmt WHILE
+ { expand_loop_continue_here (); }
+ ;
+
+save_filename:
+ { $$ = input_filename; }
+ ;
+
+save_lineno:
+ { $$ = lineno; }
+ ;
+
+lineno_labeled_stmt:
+ save_filename save_lineno stmt
+ { }
+/* | save_filename save_lineno error
+ { }
+*/
+ | save_filename save_lineno label lineno_labeled_stmt
+ { }
+ ;
+
+lineno_stmt_or_label:
+ save_filename save_lineno stmt_or_label
+ { $$ = $3; }
+ ;
+
+stmt_or_label:
+ stmt
+ { $$ = 0; }
+ | label
+ { $$ = 1; }
+ ;
+
+/* Parse a single real statement, not including any labels. */
+stmt:
+ compstmt
+ { stmt_count++; }
+ | all_iter_stmt
+ | expr ';'
+ { stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+/* It appears that this should not be done--that a non-lvalue array
+ shouldn't get an error if the value isn't used.
+ Section 3.2.2.1 says that an array lvalue gets converted to a pointer
+ if it appears as a top-level expression,
+ but says nothing about non-lvalue arrays. */
+#if 0
+ /* Call default_conversion to get an error
+ on referring to a register array if pedantic. */
+ if (TREE_CODE (TREE_TYPE ($1)) == ARRAY_TYPE
+ || TREE_CODE (TREE_TYPE ($1)) == FUNCTION_TYPE)
+ $1 = default_conversion ($1);
+#endif
+ iterator_expand ($1);
+ clear_momentary (); }
+ | simple_if ELSE
+ { c_expand_start_else ();
+ $<itype>1 = stmt_count;
+ position_after_white_space (); }
+ lineno_labeled_stmt
+ { c_expand_end_cond ();
+ if (extra_warnings && stmt_count == $<itype>1)
+ warning ("empty body in an else-statement"); }
+ | simple_if %prec IF
+ { c_expand_end_cond ();
+ /* This warning is here instead of in simple_if, because we
+ do not want a warning if an empty if is followed by an
+ else statement. Increment stmt_count so we don't
+ give a second error if this is a nested `if'. */
+ if (extra_warnings && stmt_count++ == $<itype>1)
+ warning_with_file_and_line (if_stmt_file, if_stmt_line,
+ "empty body in an if-statement"); }
+/* Make sure c_expand_end_cond is run once
+ for each call to c_expand_start_cond.
+ Otherwise a crash is likely. */
+ | simple_if ELSE error
+ { c_expand_end_cond (); }
+ | WHILE
+ { stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ /* The emit_nop used to come before emit_line_note,
+ but that made the nop seem like part of the preceding line.
+ And that was confusing when the preceding line was
+ inside of an if statement and was not really executed.
+ I think it ought to work to put the nop after the line number.
+ We will see. --rms, July 15, 1991. */
+ emit_nop (); }
+ '(' expr ')'
+ { /* Don't start the loop till we have succeeded
+ in parsing the end test. This is to make sure
+ that we end every loop we start. */
+ expand_start_loop (1);
+ emit_line_note (input_filename, lineno);
+ expand_exit_loop_if_false (NULL_PTR,
+ truthvalue_conversion ($4));
+ position_after_white_space (); }
+ lineno_labeled_stmt
+ { expand_end_loop (); }
+ | do_stmt_start
+ '(' expr ')' ';'
+ { emit_line_note (input_filename, lineno);
+ expand_exit_loop_if_false (NULL_PTR,
+ truthvalue_conversion ($3));
+ expand_end_loop ();
+ clear_momentary (); }
+/* This rule is needed to make sure we end every loop we start. */
+ | do_stmt_start error
+ { expand_end_loop ();
+ clear_momentary (); }
+ | FOR
+ '(' xexpr ';'
+ { stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ /* See comment in `while' alternative, above. */
+ emit_nop ();
+ if ($3) c_expand_expr_stmt ($3);
+ /* Next step is to call expand_start_loop_continue_elsewhere,
+ but wait till after we parse the entire for (...).
+ Otherwise, invalid input might cause us to call that
+ fn without calling expand_end_loop. */
+ }
+ xexpr ';'
+ /* Can't emit now; wait till after expand_start_loop... */
+ { $<lineno>7 = lineno;
+ $<filename>$ = input_filename; }
+ xexpr ')'
+ {
+ /* Start the loop. Doing this after parsing
+ all the expressions ensures we will end the loop. */
+ expand_start_loop_continue_elsewhere (1);
+ /* Emit the end-test, with a line number. */
+ emit_line_note ($<filename>8, $<lineno>7);
+ if ($6)
+ expand_exit_loop_if_false (NULL_PTR,
+ truthvalue_conversion ($6));
+ /* Don't let the tree nodes for $9 be discarded by
+ clear_momentary during the parsing of the next stmt. */
+ push_momentary ();
+ $<lineno>7 = lineno;
+ $<filename>8 = input_filename;
+ position_after_white_space (); }
+ lineno_labeled_stmt
+ { /* Emit the increment expression, with a line number. */
+ emit_line_note ($<filename>8, $<lineno>7);
+ expand_loop_continue_here ();
+ if ($9)
+ c_expand_expr_stmt ($9);
+ if (yychar == CONSTANT || yychar == STRING)
+ pop_momentary_nofree ();
+ else
+ pop_momentary ();
+ expand_end_loop (); }
+ | SWITCH '(' expr ')'
+ { stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ c_expand_start_case ($3);
+ /* Don't let the tree nodes for $3 be discarded by
+ clear_momentary during the parsing of the next stmt. */
+ push_momentary ();
+ position_after_white_space (); }
+ lineno_labeled_stmt
+ { expand_end_case ($3);
+ if (yychar == CONSTANT || yychar == STRING)
+ pop_momentary_nofree ();
+ else
+ pop_momentary (); }
+ | BREAK ';'
+ { stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ if ( ! expand_exit_something ())
+ error ("break statement not within loop or switch"); }
+ | CONTINUE ';'
+ { stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ if (! expand_continue_loop (NULL_PTR))
+ error ("continue statement not within a loop"); }
+ | RETURN ';'
+ { stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ c_expand_return (NULL_TREE); }
+ | RETURN expr ';'
+ { stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ c_expand_return ($2); }
+ | ASM_KEYWORD maybe_type_qual '(' expr ')' ';'
+ { stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ STRIP_NOPS ($4);
+ if ((TREE_CODE ($4) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND ($4, 0)) == STRING_CST)
+ || TREE_CODE ($4) == STRING_CST)
+ expand_asm ($4);
+ else
+ error ("argument of `asm' is not a constant string"); }
+ /* This is the case with just output operands. */
+ | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ')' ';'
+ { stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE,
+ $2 == ridpointers[(int)RID_VOLATILE],
+ input_filename, lineno); }
+ /* This is the case with input operands as well. */
+ | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':' asm_operands ')' ';'
+ { stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ c_expand_asm_operands ($4, $6, $8, NULL_TREE,
+ $2 == ridpointers[(int)RID_VOLATILE],
+ input_filename, lineno); }
+ /* This is the case with clobbered registers as well. */
+ | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':'
+ asm_operands ':' asm_clobbers ')' ';'
+ { stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ c_expand_asm_operands ($4, $6, $8, $10,
+ $2 == ridpointers[(int)RID_VOLATILE],
+ input_filename, lineno); }
+ | GOTO identifier ';'
+ { tree decl;
+ stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ decl = lookup_label ($2);
+ if (decl != 0)
+ {
+ TREE_USED (decl) = 1;
+ expand_goto (decl);
+ }
+ }
+ | GOTO '*' expr ';'
+ { if (pedantic)
+ pedwarn ("ANSI C forbids `goto *expr;'");
+ stmt_count++;
+ emit_line_note ($<filename>-1, $<lineno>0);
+ expand_computed_goto (convert (ptr_type_node, $3)); }
+ | ';'
+ ;
+
+all_iter_stmt:
+ all_iter_stmt_simple
+/* | all_iter_stmt_with_decl */
+ ;
+
+all_iter_stmt_simple:
+ FOR '(' primary ')'
+ {
+ /* The value returned by this action is */
+ /* 1 if everything is OK */
+ /* 0 in case of error or already bound iterator */
+
+ $<itype>$ = 0;
+ if (TREE_CODE ($3) != VAR_DECL)
+ error ("invalid `for (ITERATOR)' syntax");
+ else if (! ITERATOR_P ($3))
+ error ("`%s' is not an iterator",
+ IDENTIFIER_POINTER (DECL_NAME ($3)));
+ else if (ITERATOR_BOUND_P ($3))
+ error ("`for (%s)' inside expansion of same iterator",
+ IDENTIFIER_POINTER (DECL_NAME ($3)));
+ else
+ {
+ $<itype>$ = 1;
+ iterator_for_loop_start ($3);
+ }
+ }
+ lineno_labeled_stmt
+ {
+ if ($<itype>5)
+ iterator_for_loop_end ($3);
+ }
+
+/* This really should allow any kind of declaration,
+ for generality. Fix it before turning it back on.
+
+all_iter_stmt_with_decl:
+ FOR '(' ITERATOR pushlevel setspecs iterator_spec ')'
+ {
+*/ /* The value returned by this action is */
+ /* 1 if everything is OK */
+ /* 0 in case of error or already bound iterator */
+/*
+ iterator_for_loop_start ($6);
+ }
+ lineno_labeled_stmt
+ {
+ iterator_for_loop_end ($6);
+ emit_line_note (input_filename, lineno);
+ expand_end_bindings (getdecls (), 1, 0);
+ $<ttype>$ = poplevel (1, 1, 0);
+ if (yychar == CONSTANT || yychar == STRING)
+ pop_momentary_nofree ();
+ else
+ pop_momentary ();
+ }
+*/
+
+/* Any kind of label, including jump labels and case labels.
+ ANSI C accepts labels only before statements, but we allow them
+ also at the end of a compound statement. */
+
+label: CASE expr_no_commas ':'
+ { register tree value = check_case_value ($2);
+ register tree label
+ = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+
+ stmt_count++;
+
+ if (value != error_mark_node)
+ {
+ tree duplicate;
+ int success = pushcase (value, convert_and_check,
+ label, &duplicate);
+ if (success == 1)
+ error ("case label not within a switch statement");
+ else if (success == 2)
+ {
+ error ("duplicate case value");
+ error_with_decl (duplicate, "this is the first entry for that value");
+ }
+ else if (success == 3)
+ warning ("case value out of range");
+ else if (success == 5)
+ error ("case label within scope of cleanup or variable array");
+ }
+ position_after_white_space (); }
+ | CASE expr_no_commas ELLIPSIS expr_no_commas ':'
+ { register tree value1 = check_case_value ($2);
+ register tree value2 = check_case_value ($4);
+ register tree label
+ = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+
+ if (pedantic)
+ pedwarn ("ANSI C forbids case ranges");
+ stmt_count++;
+
+ if (value1 != error_mark_node && value2 != error_mark_node)
+ {
+ tree duplicate;
+ int success = pushcase_range (value1, value2,
+ convert_and_check, label,
+ &duplicate);
+ if (success == 1)
+ error ("case label not within a switch statement");
+ else if (success == 2)
+ {
+ error ("duplicate case value");
+ error_with_decl (duplicate, "this is the first entry for that value");
+ }
+ else if (success == 3)
+ warning ("case value out of range");
+ else if (success == 4)
+ warning ("empty case range");
+ else if (success == 5)
+ error ("case label within scope of cleanup or variable array");
+ }
+ position_after_white_space (); }
+ | DEFAULT ':'
+ {
+ tree duplicate;
+ register tree label
+ = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+ int success = pushcase (NULL_TREE, 0, label, &duplicate);
+ stmt_count++;
+ if (success == 1)
+ error ("default label not within a switch statement");
+ else if (success == 2)
+ {
+ error ("multiple default labels in one switch");
+ error_with_decl (duplicate, "this is the first default label");
+ }
+ position_after_white_space (); }
+ | identifier ':'
+ { tree label = define_label (input_filename, lineno, $1);
+ stmt_count++;
+ emit_nop ();
+ if (label)
+ expand_label (label);
+ position_after_white_space (); }
+ ;
+
+/* Either a type-qualifier or nothing. First thing in an `asm' statement. */
+
+maybe_type_qual:
+ /* empty */
+ { emit_line_note (input_filename, lineno);
+ $$ = NULL_TREE; }
+ | TYPE_QUAL
+ { emit_line_note (input_filename, lineno); }
+ ;
+
+xexpr:
+ /* empty */
+ { $$ = NULL_TREE; }
+ | expr
+ ;
+
+/* These are the operands other than the first string and colon
+ in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */
+asm_operands: /* empty */
+ { $$ = NULL_TREE; }
+ | nonnull_asm_operands
+ ;
+
+nonnull_asm_operands:
+ asm_operand
+ | nonnull_asm_operands ',' asm_operand
+ { $$ = chainon ($1, $3); }
+ ;
+
+asm_operand:
+ STRING '(' expr ')'
+ { $$ = build_tree_list ($1, $3); }
+ ;
+
+asm_clobbers:
+ string
+ { $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE); }
+ | asm_clobbers ',' string
+ { $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); }
+ ;
+
+/* This is what appears inside the parens in a function declarator.
+ Its value is a list of ..._TYPE nodes. */
+parmlist:
+ { pushlevel (0);
+ clear_parm_order ();
+ declare_parm_level (0); }
+ parmlist_1
+ { $$ = $2;
+ parmlist_tags_warning ();
+ poplevel (0, 0, 0); }
+ ;
+
+parmlist_1:
+ parmlist_2 ')'
+ | parms ';'
+ { tree parm;
+ if (pedantic)
+ pedwarn ("ANSI C forbids forward parameter declarations");
+ /* Mark the forward decls as such. */
+ for (parm = getdecls (); parm; parm = TREE_CHAIN (parm))
+ TREE_ASM_WRITTEN (parm) = 1;
+ clear_parm_order (); }
+ parmlist_1
+ { $$ = $4; }
+ | error ')'
+ { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); }
+ ;
+
+/* This is what appears inside the parens in a function declarator.
+ Is value is represented in the format that grokdeclarator expects. */
+parmlist_2: /* empty */
+ { $$ = get_parm_info (0); }
+ | ELLIPSIS
+ { $$ = get_parm_info (0);
+ /* Gcc used to allow this as an extension. However, it does
+ not work for all targets, and thus has been disabled.
+ Also, since func (...) and func () are indistinguishable,
+ it caused problems with the code in expand_builtin which
+ tries to verify that BUILT_IN_NEXT_ARG is being used
+ correctly. */
+ error ("ANSI C requires a named argument before `...'");
+ }
+ | parms
+ { $$ = get_parm_info (1); }
+ | parms ',' ELLIPSIS
+ { $$ = get_parm_info (0); }
+ ;
+
+parms:
+ parm
+ { push_parm_decl ($1); }
+ | parms ',' parm
+ { push_parm_decl ($3); }
+ ;
+
+/* A single parameter declaration or parameter type name,
+ as found in a parmlist. */
+parm:
+ typed_declspecs setspecs parm_declarator maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $3),
+ build_tree_list (prefix_attributes,
+ $4));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | typed_declspecs setspecs notype_declarator maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $3),
+ build_tree_list (prefix_attributes,
+ $4));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | typed_declspecs setspecs absdcl maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $3),
+ build_tree_list (prefix_attributes,
+ $4));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | declmods setspecs notype_declarator maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $3),
+ build_tree_list (prefix_attributes,
+ $4));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+
+ | declmods setspecs absdcl maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $3),
+ build_tree_list (prefix_attributes,
+ $4));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ ;
+
+/* This is used in a function definition
+ where either a parmlist or an identifier list is ok.
+ Its value is a list of ..._TYPE nodes or a list of identifiers. */
+parmlist_or_identifiers:
+ { pushlevel (0);
+ clear_parm_order ();
+ declare_parm_level (1); }
+ parmlist_or_identifiers_1
+ { $$ = $2;
+ parmlist_tags_warning ();
+ poplevel (0, 0, 0); }
+ ;
+
+parmlist_or_identifiers_1:
+ parmlist_1
+ | identifiers ')'
+ { tree t;
+ for (t = $1; t; t = TREE_CHAIN (t))
+ if (TREE_VALUE (t) == NULL_TREE)
+ error ("`...' in old-style identifier list");
+ $$ = tree_cons (NULL_TREE, NULL_TREE, $1); }
+ ;
+
+/* A nonempty list of identifiers. */
+identifiers:
+ IDENTIFIER
+ { $$ = build_tree_list (NULL_TREE, $1); }
+ | identifiers ',' IDENTIFIER
+ { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
+ ;
+
+/* A nonempty list of identifiers, including typenames. */
+identifiers_or_typenames:
+ identifier
+ { $$ = build_tree_list (NULL_TREE, $1); }
+ | identifiers_or_typenames ',' identifier
+ { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
+ ;
+
+extension:
+ EXTENSION
+ { $<itype>$ = pedantic;
+ pedantic = 0; }
+ ;
+
+/* Objective-C productions. */
+
+objcdef:
+ classdef
+ | classdecl
+ | aliasdecl
+ | protocoldef
+ | methoddef
+ | END
+ {
+ if (objc_implementation_context)
+ {
+ finish_class (objc_implementation_context);
+ objc_ivar_chain = NULL_TREE;
+ objc_implementation_context = NULL_TREE;
+ }
+ else
+ warning ("`@end' must appear in an implementation context");
+ }
+ ;
+
+/* A nonempty list of identifiers. */
+identifier_list:
+ identifier
+ { $$ = build_tree_list (NULL_TREE, $1); }
+ | identifier_list ',' identifier
+ { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
+ ;
+
+classdecl:
+ CLASS identifier_list ';'
+ {
+ objc_declare_class ($2);
+ }
+
+aliasdecl:
+ ALIAS identifier identifier ';'
+ {
+ objc_declare_alias ($2, $3);
+ }
+
+classdef:
+ INTERFACE identifier protocolrefs '{'
+ {
+ objc_interface_context = objc_ivar_context
+ = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3);
+ objc_public_flag = 0;
+ }
+ ivar_decl_list '}'
+ {
+ continue_class (objc_interface_context);
+ }
+ methodprotolist
+ END
+ {
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ }
+
+ | INTERFACE identifier protocolrefs
+ {
+ objc_interface_context
+ = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3);
+ continue_class (objc_interface_context);
+ }
+ methodprotolist
+ END
+ {
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ }
+
+ | INTERFACE identifier ':' identifier protocolrefs '{'
+ {
+ objc_interface_context = objc_ivar_context
+ = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5);
+ objc_public_flag = 0;
+ }
+ ivar_decl_list '}'
+ {
+ continue_class (objc_interface_context);
+ }
+ methodprotolist
+ END
+ {
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ }
+
+ | INTERFACE identifier ':' identifier protocolrefs
+ {
+ objc_interface_context
+ = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5);
+ continue_class (objc_interface_context);
+ }
+ methodprotolist
+ END
+ {
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ }
+
+ | IMPLEMENTATION identifier '{'
+ {
+ objc_implementation_context = objc_ivar_context
+ = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE);
+ objc_public_flag = 0;
+ }
+ ivar_decl_list '}'
+ {
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ }
+
+ | IMPLEMENTATION identifier
+ {
+ objc_implementation_context
+ = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE);
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ }
+
+ | IMPLEMENTATION identifier ':' identifier '{'
+ {
+ objc_implementation_context = objc_ivar_context
+ = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
+ objc_public_flag = 0;
+ }
+ ivar_decl_list '}'
+ {
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ }
+
+ | IMPLEMENTATION identifier ':' identifier
+ {
+ objc_implementation_context
+ = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ }
+
+ | INTERFACE identifier '(' identifier ')' protocolrefs
+ {
+ objc_interface_context
+ = start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6);
+ continue_class (objc_interface_context);
+ }
+ methodprotolist
+ END
+ {
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ }
+
+ | IMPLEMENTATION identifier '(' identifier ')'
+ {
+ objc_implementation_context
+ = start_class (CATEGORY_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ }
+ ;
+
+protocoldef:
+ PROTOCOL identifier protocolrefs
+ {
+ remember_protocol_qualifiers ();
+ objc_interface_context
+ = start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3);
+ }
+ methodprotolist END
+ {
+ forget_protocol_qualifiers();
+ finish_protocol(objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ }
+ ;
+
+protocolrefs:
+ /* empty */
+ {
+ $$ = NULL_TREE;
+ }
+ | non_empty_protocolrefs
+ ;
+
+non_empty_protocolrefs:
+ ARITHCOMPARE identifier_list ARITHCOMPARE
+ {
+ if ($1 == LT_EXPR && $3 == GT_EXPR)
+ $$ = $2;
+ else
+ YYERROR1;
+ }
+ ;
+
+ivar_decl_list:
+ ivar_decl_list visibility_spec ivar_decls
+ | ivar_decls
+ ;
+
+visibility_spec:
+ PRIVATE { objc_public_flag = 2; }
+ | PROTECTED { objc_public_flag = 0; }
+ | PUBLIC { objc_public_flag = 1; }
+ ;
+
+ivar_decls:
+ /* empty */
+ {
+ $$ = NULL_TREE;
+ }
+ | ivar_decls ivar_decl ';'
+ | ivar_decls ';'
+ {
+ if (pedantic)
+ pedwarn ("extra semicolon in struct or union specified");
+ }
+ ;
+
+
+/* There is a shift-reduce conflict here, because `components' may
+ start with a `typename'. It happens that shifting (the default resolution)
+ does the right thing, because it treats the `typename' as part of
+ a `typed_typespecs'.
+
+ It is possible that this same technique would allow the distinction
+ between `notype_initdecls' and `initdecls' to be eliminated.
+ But I am being cautious and not trying it. */
+
+ivar_decl:
+ typed_typespecs setspecs ivars
+ { $$ = $3;
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | nonempty_type_quals setspecs ivars
+ { $$ = $3;
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | error
+ { $$ = NULL_TREE; }
+ ;
+
+ivars:
+ /* empty */
+ { $$ = NULL_TREE; }
+ | ivar_declarator
+ | ivars ',' ivar_declarator
+ ;
+
+ivar_declarator:
+ declarator
+ {
+ $$ = add_instance_variable (objc_ivar_context,
+ objc_public_flag,
+ $1, current_declspecs,
+ NULL_TREE);
+ }
+ | declarator ':' expr_no_commas
+ {
+ $$ = add_instance_variable (objc_ivar_context,
+ objc_public_flag,
+ $1, current_declspecs, $3);
+ }
+ | ':' expr_no_commas
+ {
+ $$ = add_instance_variable (objc_ivar_context,
+ objc_public_flag,
+ NULL_TREE,
+ current_declspecs, $2);
+ }
+ ;
+
+methoddef:
+ '+'
+ {
+ remember_protocol_qualifiers ();
+ if (objc_implementation_context)
+ objc_inherit_code = CLASS_METHOD_DECL;
+ else
+ fatal ("method definition not in class context");
+ }
+ methoddecl
+ {
+ forget_protocol_qualifiers ();
+ add_class_method (objc_implementation_context, $3);
+ start_method_def ($3);
+ objc_method_context = $3;
+ }
+ optarglist
+ {
+ continue_method_def ();
+ }
+ compstmt_or_error
+ {
+ finish_method_def ();
+ objc_method_context = NULL_TREE;
+ }
+
+ | '-'
+ {
+ remember_protocol_qualifiers ();
+ if (objc_implementation_context)
+ objc_inherit_code = INSTANCE_METHOD_DECL;
+ else
+ fatal ("method definition not in class context");
+ }
+ methoddecl
+ {
+ forget_protocol_qualifiers ();
+ add_instance_method (objc_implementation_context, $3);
+ start_method_def ($3);
+ objc_method_context = $3;
+ }
+ optarglist
+ {
+ continue_method_def ();
+ }
+ compstmt_or_error
+ {
+ finish_method_def ();
+ objc_method_context = NULL_TREE;
+ }
+ ;
+
+/* the reason for the strange actions in this rule
+ is so that notype_initdecls when reached via datadef
+ can find a valid list of type and sc specs in $0. */
+
+methodprotolist:
+ /* empty */
+ | {$<ttype>$ = NULL_TREE; } methodprotolist2
+ ;
+
+methodprotolist2: /* eliminates a shift/reduce conflict */
+ methodproto
+ | datadef
+ | methodprotolist2 methodproto
+ | methodprotolist2 {$<ttype>$ = NULL_TREE; } datadef
+ ;
+
+semi_or_error:
+ ';'
+ | error
+ ;
+
+methodproto:
+ '+'
+ {
+ objc_inherit_code = CLASS_METHOD_DECL;
+ }
+ methoddecl
+ {
+ add_class_method (objc_interface_context, $3);
+ }
+ semi_or_error
+
+ | '-'
+ {
+ objc_inherit_code = INSTANCE_METHOD_DECL;
+ }
+ methoddecl
+ {
+ add_instance_method (objc_interface_context, $3);
+ }
+ semi_or_error
+ ;
+
+methoddecl:
+ '(' typename ')' unaryselector
+ {
+ $$ = build_method_decl (objc_inherit_code, $2, $4, NULL_TREE);
+ }
+
+ | unaryselector
+ {
+ $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, NULL_TREE);
+ }
+
+ | '(' typename ')' keywordselector optparmlist
+ {
+ $$ = build_method_decl (objc_inherit_code, $2, $4, $5);
+ }
+
+ | keywordselector optparmlist
+ {
+ $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, $2);
+ }
+ ;
+
+/* "optarglist" assumes that start_method_def has already been called...
+ if it is not, the "xdecls" will not be placed in the proper scope */
+
+optarglist:
+ /* empty */
+ | ';' myxdecls
+ ;
+
+/* to get around the following situation: "int foo (int a) int b; {}" that
+ is synthesized when parsing "- a:a b:b; id c; id d; { ... }" */
+
+myxdecls:
+ /* empty */
+ | mydecls
+ ;
+
+mydecls:
+ mydecl
+ | errstmt
+ | mydecls mydecl
+ | mydecl errstmt
+ ;
+
+mydecl:
+ typed_declspecs setspecs myparms ';'
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | typed_declspecs ';'
+ { shadow_tag ($1); }
+ | declmods ';'
+ { pedwarn ("empty declaration"); }
+ ;
+
+myparms:
+ myparm
+ { push_parm_decl ($1); }
+ | myparms ',' myparm
+ { push_parm_decl ($3); }
+ ;
+
+/* A single parameter declaration or parameter type name,
+ as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */
+
+myparm:
+ parm_declarator maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $1),
+ build_tree_list (prefix_attributes,
+ $2)); }
+ | notype_declarator maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $1),
+ build_tree_list (prefix_attributes,
+ $2)); }
+ | absdcl maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $1),
+ build_tree_list (prefix_attributes,
+ $2)); }
+ ;
+
+optparmlist:
+ /* empty */
+ {
+ $$ = NULL_TREE;
+ }
+ | ',' ELLIPSIS
+ {
+ /* oh what a kludge! */
+ $$ = (tree)1;
+ }
+ | ','
+ {
+ pushlevel (0);
+ }
+ parmlist_2
+ {
+ /* returns a tree list node generated by get_parm_info */
+ $$ = $3;
+ poplevel (0, 0, 0);
+ }
+ ;
+
+unaryselector:
+ selector
+ ;
+
+keywordselector:
+ keyworddecl
+
+ | keywordselector keyworddecl
+ {
+ $$ = chainon ($1, $2);
+ }
+ ;
+
+selector:
+ IDENTIFIER
+ | TYPENAME
+ | OBJECTNAME
+ | reservedwords
+ ;
+
+reservedwords:
+ ENUM { $$ = get_identifier (token_buffer); }
+ | STRUCT { $$ = get_identifier (token_buffer); }
+ | UNION { $$ = get_identifier (token_buffer); }
+ | IF { $$ = get_identifier (token_buffer); }
+ | ELSE { $$ = get_identifier (token_buffer); }
+ | WHILE { $$ = get_identifier (token_buffer); }
+ | DO { $$ = get_identifier (token_buffer); }
+ | FOR { $$ = get_identifier (token_buffer); }
+ | SWITCH { $$ = get_identifier (token_buffer); }
+ | CASE { $$ = get_identifier (token_buffer); }
+ | DEFAULT { $$ = get_identifier (token_buffer); }
+ | BREAK { $$ = get_identifier (token_buffer); }
+ | CONTINUE { $$ = get_identifier (token_buffer); }
+ | RETURN { $$ = get_identifier (token_buffer); }
+ | GOTO { $$ = get_identifier (token_buffer); }
+ | ASM_KEYWORD { $$ = get_identifier (token_buffer); }
+ | SIZEOF { $$ = get_identifier (token_buffer); }
+ | TYPEOF { $$ = get_identifier (token_buffer); }
+ | ALIGNOF { $$ = get_identifier (token_buffer); }
+ | TYPESPEC | TYPE_QUAL
+ ;
+
+keyworddecl:
+ selector ':' '(' typename ')' identifier
+ {
+ $$ = build_keyword_decl ($1, $4, $6);
+ }
+
+ | selector ':' identifier
+ {
+ $$ = build_keyword_decl ($1, NULL_TREE, $3);
+ }
+
+ | ':' '(' typename ')' identifier
+ {
+ $$ = build_keyword_decl (NULL_TREE, $3, $5);
+ }
+
+ | ':' identifier
+ {
+ $$ = build_keyword_decl (NULL_TREE, NULL_TREE, $2);
+ }
+ ;
+
+messageargs:
+ selector
+ | keywordarglist
+ ;
+
+keywordarglist:
+ keywordarg
+ | keywordarglist keywordarg
+ {
+ $$ = chainon ($1, $2);
+ }
+ ;
+
+
+keywordexpr:
+ nonnull_exprlist
+ {
+ if (TREE_CHAIN ($1) == NULL_TREE)
+ /* just return the expr., remove a level of indirection */
+ $$ = TREE_VALUE ($1);
+ else
+ /* we have a comma expr., we will collapse later */
+ $$ = $1;
+ }
+ ;
+
+keywordarg:
+ selector ':' keywordexpr
+ {
+ $$ = build_tree_list ($1, $3);
+ }
+ | ':' keywordexpr
+ {
+ $$ = build_tree_list (NULL_TREE, $2);
+ }
+ ;
+
+receiver:
+ expr
+ | CLASSNAME
+ {
+ $$ = get_class_reference ($1);
+ }
+ ;
+
+objcmessageexpr:
+ '['
+ { objc_receiver_context = 1; }
+ receiver
+ { objc_receiver_context = 0; }
+ messageargs ']'
+ {
+ $$ = build_tree_list ($3, $5);
+ }
+ ;
+
+selectorarg:
+ selector
+ | keywordnamelist
+ ;
+
+keywordnamelist:
+ keywordname
+ | keywordnamelist keywordname
+ {
+ $$ = chainon ($1, $2);
+ }
+ ;
+
+keywordname:
+ selector ':'
+ {
+ $$ = build_tree_list ($1, NULL_TREE);
+ }
+ | ':'
+ {
+ $$ = build_tree_list (NULL_TREE, NULL_TREE);
+ }
+ ;
+
+objcselectorexpr:
+ SELECTOR '(' selectorarg ')'
+ {
+ $$ = $3;
+ }
+ ;
+
+objcprotocolexpr:
+ PROTOCOL '(' identifier ')'
+ {
+ $$ = $3;
+ }
+ ;
+
+/* extension to support C-structures in the archiver */
+
+objcencodeexpr:
+ ENCODE '(' typename ')'
+ {
+ $$ = groktypename ($3);
+ }
+ ;
+
+%%
diff --git a/gnu/usr.bin/gcc/objc/objc-tree.def b/gnu/usr.bin/gcc/objc/objc-tree.def
new file mode 100644
index 00000000000..03f0c715776
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/objc-tree.def
@@ -0,0 +1,37 @@
+/* This file contains the definitions and documentation for the
+ additional tree codes used in the Objective C front end (see tree.def
+ for the standard codes).
+ Copyright (C) 1990 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. */
+
+
+/* Objective-C types. */
+DEFTREECODE (CLASS_INTERFACE_TYPE, "class_interface_type", "t", 0)
+DEFTREECODE (CLASS_IMPLEMENTATION_TYPE, "class_implementation_type", "t", 0)
+DEFTREECODE (CATEGORY_INTERFACE_TYPE, "category_interface_type", "t", 0)
+DEFTREECODE (CATEGORY_IMPLEMENTATION_TYPE,"category_implementation_type","t",0)
+DEFTREECODE (PROTOCOL_INTERFACE_TYPE, "protocol_interface_type", "t", 0)
+
+/* Objective-C decls. */
+DEFTREECODE (KEYWORD_DECL, "keyword_decl", "d", 0)
+DEFTREECODE (INSTANCE_METHOD_DECL, "instance_method_decl", "d", 0)
+DEFTREECODE (CLASS_METHOD_DECL, "class_method_decl", "d", 0)
+
+/* Objective-C constants. */
+DEFTREECODE (OBJC_STRING_CST, "objc_string_cst", "c", 3)
diff --git a/gnu/usr.bin/gcc/objc/objc.gperf b/gnu/usr.bin/gcc/objc/objc.gperf
new file mode 100644
index 00000000000..407459f1589
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/objc.gperf
@@ -0,0 +1,64 @@
+%{
+/* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ objc.gperf */
+%}
+struct resword { char *name; short token; enum rid rid; };
+%%
+@defs, DEFS, NORID
+@encode, ENCODE, NORID
+@end, END, NORID
+@implementation, IMPLEMENTATION, NORID
+@interface, INTERFACE, NORID
+@public, PUBLIC, NORID
+@selector, SELECTOR, NORID
+__alignof, ALIGNOF, NORID
+__alignof__, ALIGNOF, NORID
+__asm, ASM, NORID
+__asm__, ASM, NORID
+__attribute, ATTRIBUTE, NORID
+__attribute__, ATTRIBUTE, NORID
+__const, TYPE_QUAL, RID_CONST
+__const__, TYPE_QUAL, RID_CONST
+__extension__, EXTENSION, NORID
+__inline, SCSPEC, RID_INLINE
+__inline__, SCSPEC, RID_INLINE
+__signed, TYPESPEC, RID_SIGNED
+__signed__, TYPESPEC, RID_SIGNED
+__typeof, TYPEOF, NORID
+__typeof__, TYPEOF, NORID
+__volatile, TYPE_QUAL, RID_VOLATILE
+__volatile__, TYPE_QUAL, RID_VOLATILE
+asm, ASM, NORID
+auto, SCSPEC, RID_AUTO
+break, BREAK, NORID
+case, CASE, NORID
+char, TYPESPEC, RID_CHAR
+const, TYPE_QUAL, RID_CONST
+continue, CONTINUE, NORID
+default, DEFAULT, NORID
+do, DO, NORID
+double, TYPESPEC, RID_DOUBLE
+else, ELSE, NORID
+enum, ENUM, NORID
+extern, SCSPEC, RID_EXTERN
+float, TYPESPEC, RID_FLOAT
+for, FOR, NORID
+goto, GOTO, NORID
+if, IF, NORID
+inline, SCSPEC, RID_INLINE
+int, TYPESPEC, RID_INT
+long, TYPESPEC, RID_LONG
+register, SCSPEC, RID_REGISTER
+return, RETURN, NORID
+short, TYPESPEC, RID_SHORT
+signed, TYPESPEC, RID_SIGNED
+sizeof, SIZEOF, NORID
+static, SCSPEC, RID_STATIC
+struct, STRUCT, NORID
+switch, SWITCH, NORID
+typedef, SCSPEC, RID_TYPEDEF
+typeof, TYPEOF, NORID
+union, UNION, NORID
+unsigned, TYPESPEC, RID_UNSIGNED
+void, TYPESPEC, RID_VOID
+volatile, TYPE_QUAL, RID_VOLATILE
+while, WHILE, NORID
diff --git a/gnu/usr.bin/gcc/objc/thr-decosf1.c b/gnu/usr.bin/gcc/objc/thr-decosf1.c
new file mode 100644
index 00000000000..0f7063b7e83
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/thr-decosf1.c
@@ -0,0 +1,281 @@
+/* GNU Objective C Runtime Thread Interface
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */
+
+/* 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. */
+
+#include <pthread.h>
+#include <objc/thr.h>
+#include "runtime.h"
+
+/* Key structure for maintaining thread specific storage */
+static pthread_key_t _objc_thread_storage;
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
+int
+__objc_init_thread_system(void)
+{
+ /* Initialize the thread storage key */
+ return pthread_keycreate(&_objc_thread_storage, NULL);
+}
+
+/* Close the threads subsystem. */
+int
+__objc_close_thread_system(void)
+{
+ /* Destroy the thread storage key */
+ /* Not implemented yet */
+ /* return pthread_key_delete(&_objc_thread_storage); */
+ return 0;
+}
+
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
+objc_thread_t
+__objc_thread_detach(void (*func)(void *arg), void *arg)
+{
+ objc_thread_t thread_id;
+ pthread_t new_thread_handle;
+
+ if (pthread_create(&new_thread_handle, pthread_attr_default,
+ (void *)func, arg) == 0)
+ {
+ /* ??? May not work! (64bit) */
+ thread_id = *(objc_thread_t *)&new_thread_handle;
+ pthread_detach(&new_thread_handle); /* Fully detach thread. */
+ }
+ else
+ thread_id = NULL;
+
+ return thread_id;
+}
+
+/* Set the current thread's priority. */
+int
+__objc_thread_set_priority(int priority)
+{
+ int sys_priority = 0;
+
+ switch (priority)
+ {
+ case OBJC_THREAD_INTERACTIVE_PRIORITY:
+ sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2;
+ break;
+ default:
+ case OBJC_THREAD_BACKGROUND_PRIORITY:
+ sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
+ break;
+ case OBJC_THREAD_LOW_PRIORITY:
+ sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
+ break;
+ }
+
+ /* Change the priority. */
+ if (pthread_setprio(pthread_self(), sys_priority) >= 0)
+ return 0;
+ else
+ /* Failed */
+ return -1;
+}
+
+/* Return the current thread's priority. */
+int
+__objc_thread_get_priority(void)
+{
+ int sys_priority;
+
+ if ((sys_priority = pthread_getprio(pthread_self())) >= 0) {
+ if (sys_priority >= PRI_FG_MIN_NP && sys_priority <= PRI_FG_MAX_NP)
+ return OBJC_THREAD_INTERACTIVE_PRIORITY;
+ if (sys_priority >= PRI_BG_MIN_NP && sys_priority <= PRI_BG_MAX_NP)
+ return OBJC_THREAD_BACKGROUND_PRIORITY;
+ return OBJC_THREAD_LOW_PRIORITY;
+ }
+
+ /* Failed */
+ return -1;
+}
+
+/* Yield our process time to another thread. */
+void
+__objc_thread_yield(void)
+{
+ pthread_yield();
+}
+
+/* Terminate the current thread. */
+int
+__objc_thread_exit(void)
+{
+ /* exit the thread */
+ pthread_exit(&__objc_thread_exit_status);
+
+ /* Failed if we reached here */
+ return -1;
+}
+
+/* Returns an integer value which uniquely describes a thread. */
+objc_thread_t
+__objc_thread_id(void)
+{
+ pthread_t self = pthread_self();
+
+ return (objc_thread_t) pthread_getunique_np (&self);
+}
+
+/* Sets the thread's local storage pointer. */
+int
+__objc_thread_set_data(void *value)
+{
+ return pthread_setspecific(_objc_thread_storage, value);
+}
+
+/* Returns the thread's local storage pointer. */
+void *
+__objc_thread_get_data(void)
+{
+ void *value = NULL;
+
+ if ( !(pthread_getspecific(_objc_thread_storage, &value)) )
+ return value;
+
+ return NULL;
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
+{
+ if (pthread_mutex_init((pthread_mutex_t *)(&(mutex->backend)),
+ pthread_mutexattr_default))
+ return -1;
+ else
+ return 0;
+}
+
+/* Deallocate a mutex. */
+int
+__objc_mutex_deallocate(objc_mutex_t mutex)
+{
+ if (pthread_mutex_destroy((pthread_mutex_t *)(&(mutex->backend))))
+ return -1;
+ else
+ return 0;
+}
+
+/* Grab a lock on a mutex. */
+int
+__objc_mutex_lock(objc_mutex_t mutex)
+{
+ return pthread_mutex_lock((pthread_mutex_t *)(&(mutex->backend)));
+}
+
+/* Try to grab a lock on a mutex. */
+int
+__objc_mutex_trylock(objc_mutex_t mutex)
+{
+ if (pthread_mutex_trylock((pthread_mutex_t *)(&(mutex->backend))) != 1)
+ return -1;
+ else
+ return 0;
+}
+
+/* Unlock the mutex */
+int
+__objc_mutex_unlock(objc_mutex_t mutex)
+{
+ return pthread_mutex_unlock((pthread_mutex_t *)(&(mutex->backend)));
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+
+ /*
+ if (pthread_cond_init((pthread_cond_t *)(&(condition->backend)), NULL))
+ return -1;
+ else
+ return 0;
+ */
+}
+
+/* Deallocate a condition. */
+int
+__objc_condition_deallocate(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+
+ /*
+ return pthread_cond_destroy((pthread_cond_t *)(&(condition->backend)));
+ */
+}
+
+/* Wait on the condition */
+int
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ /* Unimplemented. */
+ return -1;
+
+ /*
+ return pthread_cond_wait((pthread_cond_t *)(&(condition->backend)),
+ (pthread_mutex_t *)(&(mutex->backend)));
+ */
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+
+ /*
+ return pthread_cond_broadcast((pthread_cond_t *)(&(condition->backend)));
+ */
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__objc_condition_signal(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+
+ /*
+ return pthread_cond_signal((pthread_cond_t *)(&(condition->backend)));
+ */
+}
+
+/* End of File */
diff --git a/gnu/usr.bin/gcc/objc/thr-irix.c b/gnu/usr.bin/gcc/objc/thr-irix.c
new file mode 100644
index 00000000000..528a3e3a434
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/thr-irix.c
@@ -0,0 +1,235 @@
+/* GNU Objective C Runtime Thread Interface - SGI IRIX Implementation
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */
+
+/* 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. */
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/sysmp.h>
+#include <sys/prctl.h>
+#include <ulocks.h>
+#include <objc/thr.h>
+#include "runtime.h"
+
+/* Key structure for maintaining thread specific storage */
+static void * __objc_shared_arena_handle = NULL;
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
+int
+__objc_init_thread_system(void)
+{
+ /* Name of IRIX arena. */
+ char arena_name[64];
+
+ DEBUG_PRINTF("__objc_init_thread_system\n");
+
+ /* Construct a temporary name for arena. */
+ sprintf(arena_name, "/usr/tmp/objc_%05u", (unsigned)getpid());
+
+ /* Up to 256 threads. Arena only for threads. */
+ usconfig(CONF_INITUSERS, 256);
+ usconfig(CONF_ARENATYPE, US_SHAREDONLY);
+
+ /* Initialize the arena */
+ if (!(__objc_shared_arena_handle = usinit(arena_name)))
+ /* Failed */
+ return -1;
+
+ return 0;
+}
+
+/* Close the threads subsystem. */
+int
+__objc_close_thread_system(void)
+{
+ return 0;
+}
+
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
+objc_thread_t
+__objc_thread_detach(void (*func)(void *arg), void *arg)
+{
+ objc_thread_t thread_id;
+ int sys_id;
+
+ if ((sys_id = sproc((void *)func, PR_SALL, arg)) >= 0)
+ thread_id = (objc_thread_t)sys_id;
+ else
+ thread_id = NULL;
+
+ return thread_id;
+}
+
+/* Set the current thread's priority. */
+int
+__objc_thread_set_priority(int priority)
+{
+ /* Not implemented yet */
+ return -1;
+}
+
+/* Return the current thread's priority. */
+int
+__objc_thread_get_priority(void)
+{
+ /* Not implemented yet */
+ return OBJC_THREAD_INTERACTIVE_PRIORITY;
+}
+
+/* Yield our process time to another thread. */
+void
+__objc_thread_yield(void)
+{
+ sginap(0);
+}
+
+/* Terminate the current thread. */
+int
+__objc_thread_exit(void)
+{
+ /* IRIX only has exit. */
+ exit(__objc_thread_exit_status);
+
+ /* Failed if we reached here */
+ return -1;
+}
+
+/* Returns an integer value which uniquely describes a thread. */
+objc_thread_t
+__objc_thread_id(void)
+{
+ /* Threads are processes. */
+ return (objc_thread_t)get_pid();
+}
+
+/* Sets the thread's local storage pointer. */
+int
+__objc_thread_set_data(void *value)
+{
+ *((void **)&PRDA->usr_prda) = value;
+ return 0;
+}
+
+/* Returns the thread's local storage pointer. */
+void *
+__objc_thread_get_data(void)
+{
+ return *((void **)&PRDA->usr_prda);
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
+{
+ if (!( (ulock_t)(mutex->backend) = usnewlock(__objc_shared_arena_handle) ))
+ return -1;
+ else
+ return 0;
+}
+
+/* Deallocate a mutex. */
+int
+__objc_mutex_deallocate(objc_mutex_t mutex)
+{
+ usfreelock((ulock_t)(mutex->backend), __objc_shared_arena_handle);
+ return 0;
+}
+
+/* Grab a lock on a mutex. */
+int
+__objc_mutex_lock(objc_mutex_t mutex)
+{
+ if (ussetlock((ulock_t)(mutex->backend)) == 0)
+ return -1;
+ else
+ return 0;
+}
+
+/* Try to grab a lock on a mutex. */
+int
+__objc_mutex_trylock(objc_mutex_t mutex)
+{
+ if (ustestlock((ulock_t)(mutex->backend)) == 0)
+ return -1;
+ else
+ return 0;
+}
+
+/* Unlock the mutex */
+int
+__objc_mutex_unlock(objc_mutex_t mutex)
+{
+ usunsetlock((ulock_t)(mutex->backend));
+ return 0;
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Deallocate a condition. */
+int
+__objc_condition_deallocate(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Wait on the condition */
+int
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__objc_condition_signal(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* End of File */
diff --git a/gnu/usr.bin/gcc/objc/thr-mach.c b/gnu/usr.bin/gcc/objc/thr-mach.c
new file mode 100644
index 00000000000..44af0c1e286
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/thr-mach.c
@@ -0,0 +1,312 @@
+/* GNU Objective C Runtime Thread Implementation
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
+ Modified for Mach threads by Bill Bumgarner <bbum@friday.com>
+ Condition functions added by Mircea Oancea <mircea@first.elcom.pub.ro>
+
+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. */
+
+/* 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. */
+
+#include <mach/mach.h>
+#include <mach/cthreads.h>
+#include <objc/thr.h>
+#include "runtime.h"
+
+/*
+ Obtain the maximum thread priority that can set for t. Under the
+ mach threading model, it is possible for the developer to adjust the
+ maximum priority downward only-- cannot be raised without superuser
+ privileges. Once lowered, it cannot be raised.
+ */
+static int __mach_get_max_thread_priority(cthread_t t, int *base)
+{
+ thread_t threadP;
+ kern_return_t error;
+ struct thread_sched_info info;
+ unsigned int info_count=THREAD_SCHED_INFO_COUNT;
+
+ if (t == NULL)
+ return -1;
+
+ threadP = cthread_thread(t); /* get thread underlying */
+
+ error=thread_info(threadP, THREAD_SCHED_INFO,
+ (thread_info_t)&info, &info_count);
+
+ if (error != KERN_SUCCESS)
+ return -1;
+
+ if (base != NULL)
+ *base = info.base_priority;
+
+ return info.max_priority;
+}
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
+int
+__objc_init_thread_system(void)
+{
+ return 0;
+}
+
+/* Close the threads subsystem. */
+int
+__objc_close_thread_system(void)
+{
+ return 0;
+}
+
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
+objc_thread_t
+__objc_thread_detach(void (*func)(void *arg), void *arg)
+{
+ objc_thread_t thread_id;
+ cthread_t new_thread_handle;
+
+ /* create thread */
+ new_thread_handle = cthread_fork((cthread_fn_t)func, arg);
+
+ if(new_thread_handle)
+ {
+ /* this is not terribly portable */
+ thread_id = *(objc_thread_t *)&new_thread_handle;
+ cthread_detach(new_thread_handle);
+ }
+ else
+ thread_id = NULL;
+
+ return thread_id;
+}
+
+/* Set the current thread's priority. */
+int
+__objc_thread_set_priority(int priority)
+{
+ objc_thread_t *t = objc_thread_id();
+ cthread_t cT = (cthread_t) t;
+ int maxPriority = __mach_get_max_thread_priority(cT, NULL);
+ int sys_priority = 0;
+
+ if (maxPriority == -1)
+ return -1;
+
+ switch (priority)
+ {
+ case OBJC_THREAD_INTERACTIVE_PRIORITY:
+ sys_priority = maxPriority;
+ break;
+ case OBJC_THREAD_BACKGROUND_PRIORITY:
+ sys_priority = (maxPriority * 2) / 3;
+ break;
+ case OBJC_THREAD_LOW_PRIORITY:
+ sys_priority = maxPriority / 3;
+ break;
+ default:
+ return -1;
+ }
+
+ if (sys_priority == 0)
+ return -1;
+
+ /* Change the priority */
+ if (cthread_priority(cT, sys_priority, 0) == KERN_SUCCESS)
+ return 0;
+ else
+ return -1;
+}
+
+/* Return the current thread's priority. */
+int
+__objc_thread_get_priority(void)
+{
+ objc_thread_t *t = objc_thread_id();
+ cthread_t cT = (cthread_t) t; /* see objc_thread_id() */
+ int basePriority;
+ int maxPriority;
+ int sys_priority = 0;
+
+ int interactiveT, backgroundT, lowT; /* thresholds */
+
+ maxPriority = __mach_get_max_thread_priority(cT, &basePriority);
+
+ if(maxPriority == -1)
+ return -1;
+
+ if (basePriority > ( (maxPriority * 2) / 3))
+ return OBJC_THREAD_INTERACTIVE_PRIORITY;
+
+ if (basePriority > ( maxPriority / 3))
+ return OBJC_THREAD_BACKGROUND_PRIORITY;
+
+ return OBJC_THREAD_LOW_PRIORITY;
+}
+
+/* Yield our process time to another thread. */
+void
+__objc_thread_yield(void)
+{
+ cthread_yield();
+}
+
+/* Terminate the current thread. */
+int
+__objc_thread_exit(void)
+{
+ /* exit the thread */
+ cthread_exit(&__objc_thread_exit_status);
+
+ /* Failed if we reached here */
+ return -1;
+}
+
+/* Returns an integer value which uniquely describes a thread. */
+objc_thread_t
+__objc_thread_id(void)
+{
+ cthread_t self = cthread_self();
+
+ return *(objc_thread_t *)&self;
+}
+
+/* Sets the thread's local storage pointer. */
+int
+__objc_thread_set_data(void *value)
+{
+ cthread_set_data(cthread_self(), (any_t) value);
+ return 0;
+}
+
+/* Returns the thread's local storage pointer. */
+void *
+__objc_thread_get_data(void)
+{
+ return (void *) cthread_data(cthread_self());
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
+{
+ int err = 0;
+ mutex->backend = objc_malloc(sizeof(struct mutex));
+
+ err = mutex_init((mutex_t)(mutex->backend));
+
+ if (err != 0)
+ {
+ objc_free(mutex->backend);
+ return -1;
+ }
+ else
+ return 0;
+}
+
+/* Deallocate a mutex. */
+int
+__objc_mutex_deallocate(objc_mutex_t mutex)
+{
+ mutex_clear((mutex_t)(mutex->backend));
+
+ objc_free(mutex->backend);
+ mutex->backend = NULL;
+ return 0;
+}
+
+/* Grab a lock on a mutex. */
+int
+__objc_mutex_lock(objc_mutex_t mutex)
+{
+ mutex_lock((mutex_t)(mutex->backend));
+ return 0;
+}
+
+/* Try to grab a lock on a mutex. */
+int
+__objc_mutex_trylock(objc_mutex_t mutex)
+{
+ if (mutex_try_lock((mutex_t)(mutex->backend)) == 0)
+ return -1;
+ else
+ return 0;
+}
+
+/* Unlock the mutex */
+int
+__objc_mutex_unlock(objc_mutex_t mutex)
+{
+ mutex_unlock((mutex_t)(mutex->backend));
+ return 0;
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ condition->backend = objc_malloc(sizeof(struct condition));
+ condition_init((condition_t)(condition->backend));
+ return 0;
+}
+
+/* Deallocate a condition. */
+int
+__objc_condition_deallocate(objc_condition_t condition)
+{
+ condition_clear((condition_t)(condition->backend));
+ objc_free(condition->backend);
+ condition->backend = NULL;
+ return 0;
+}
+
+/* Wait on the condition */
+int
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ condition_wait((condition_t)(condition->backend),
+ (mutex_t)(mutex->backend));
+ return 0;
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ condition_broadcast((condition_t)(condition->backend));
+ return 0;
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__objc_condition_signal(objc_condition_t condition)
+{
+ condition_signal((condition_t)(condition->backend));
+ return 0;
+}
+
+/* End of File */
diff --git a/gnu/usr.bin/gcc/objc/thr-os2.c b/gnu/usr.bin/gcc/objc/thr-os2.c
new file mode 100644
index 00000000000..a0d7d436613
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/thr-os2.c
@@ -0,0 +1,267 @@
+/* GNU Objective C Runtime Thread Interface - OS/2 emx Implementation
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Thomas Baier (baier@ci.tuwien.ac.at)
+
+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. */
+
+/* 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. */
+
+#include <objc/thr.h>
+#include "runtime.h"
+
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSPROCESS
+
+/*
+ * conflicts with objc.h: SEL, BOOL, id
+ * solution: prefixing those with _OS2_ before including <os2.h>
+ */
+#define SEL _OS2_SEL
+#define BOOL _OS2_BOOL
+#define id _OS2_id
+#include <os2.h>
+#undef id
+#undef SEL
+#undef BOOL
+
+#include <stdlib.h>
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
+int
+__objc_init_thread_system(void)
+{
+ return 0;
+}
+
+/* Close the threads subsystem. */
+int
+__objc_close_thread_system(void)
+{
+ return 0;
+}
+
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
+objc_thread_t
+__objc_thread_detach(void (*func)(void *arg), void *arg)
+{
+ int thread_id = 0;
+
+ if ((thread_id = _beginthread (func,NULL,32768,arg)) < 0)
+ thread_id = 0;
+
+ return (objc_thread_t)thread_id;
+}
+
+/* Set the current thread's priority. */
+int
+__objc_thread_set_priority(int priority)
+{
+ ULONG sys_class = 0;
+ ULONG sys_priority = 0;
+
+ /* OBJC_THREAD_INTERACTIVE_PRIORITY -> PRTYC_FOREGROUNDSERVER
+ * OBJC_THREAD_BACKGROUND_PRIORITY -> PRTYC_REGULAR
+ * OBJC_THREAD_LOW_PRIORITY -> PRTYC_IDLETIME */
+
+ switch (priority) {
+ case OBJC_THREAD_INTERACTIVE_PRIORITY:
+ sys_class = PRTYC_REGULAR;
+ sys_priority = 10;
+ break;
+ default:
+ case OBJC_THREAD_BACKGROUND_PRIORITY:
+ sys_class = PRTYC_IDLETIME;
+ sys_priority = 25;
+ break;
+ case OBJC_THREAD_LOW_PRIORITY:
+ sys_class = PRTYC_IDLETIME;
+ sys_priority = 0;
+ break;
+ }
+
+ /* Change priority */
+ if (!DosSetPriority (PRTYS_THREAD,sys_class,sys_priority,*_threadid))
+ return 0;
+ else
+ return -1;
+}
+
+/* Return the current thread's priority. */
+int
+__objc_thread_get_priority(void)
+{
+ PTIB ptib;
+ PPIB ppib;
+
+ /* get information about current thread */
+ DosGetInfoBlocks (&ptib,&ppib);
+
+ switch (ptib->tib_ptib2->tib2_ulpri)
+ {
+ case PRTYC_IDLETIME:
+ case PRTYC_REGULAR:
+ case PRTYC_TIMECRITICAL:
+ case PRTYC_FOREGROUNDSERVER:
+ default:
+ return OBJC_THREAD_INTERACTIVE_PRIORITY;
+ }
+
+ return -1;
+}
+
+/* Yield our process time to another thread. */
+void
+__objc_thread_yield(void)
+{
+ DosSleep (0);
+}
+
+/* Terminate the current thread. */
+int
+__objc_thread_exit(void)
+{
+ /* terminate the thread, NEVER use DosExit () */
+ _endthread ();
+
+ /* Failed if we reached here */
+ return -1;
+}
+
+/* Returns an integer value which uniquely describes a thread. */
+objc_thread_t
+__objc_thread_id(void)
+{
+ return (objc_thread_t) *_threadid;
+}
+
+/* Sets the thread's local storage pointer. */
+int
+__objc_thread_set_data(void *value)
+{
+ *_threadstore () = value;
+
+ return 0;
+}
+
+/* Returns the thread's local storage pointer. */
+void *
+__objc_thread_get_data(void)
+{
+ return *_threadstore ();
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
+{
+ if (DosCreateMutexSem (NULL, (HMTX)(&(mutex->backend)),0L,0) > 0)
+ return -1;
+ else
+ return 0;
+}
+
+/* Deallocate a mutex. */
+int
+__objc_mutex_deallocate(objc_mutex_t mutex)
+{
+ DosCloseMutexSem ((HMTX)(mutex->backend));
+ return 0;
+}
+
+/* Grab a lock on a mutex. */
+int
+__objc_mutex_lock(objc_mutex_t mutex)
+{
+ if (DosRequestMutexSem ((HMTX)(mutex->backend),-1L) != 0)
+ return -1;
+ else
+ return 0;
+}
+
+/* Try to grab a lock on a mutex. */
+int
+__objc_mutex_trylock(objc_mutex_t mutex)
+{
+ if (DosRequestMutexSem ((HMTX)(mutex->backend),0L) != 0)
+ return -1;
+ else
+ return 0;
+}
+
+/* Unlock the mutex */
+int
+__objc_mutex_unlock(objc_mutex_t mutex)
+{
+ if (DosReleaseMutexSem((HMTX)(mutex->backend)) != 0)
+ return -1;
+ else
+ return 0;
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Deallocate a condition. */
+int
+__objc_condition_deallocate(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Wait on the condition */
+int
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__objc_condition_signal(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* End of File */
diff --git a/gnu/usr.bin/gcc/objc/thr-posix.c b/gnu/usr.bin/gcc/objc/thr-posix.c
new file mode 100644
index 00000000000..5b40f711be8
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/thr-posix.c
@@ -0,0 +1,229 @@
+/* GNU Objective C Runtime Thread Interface for POSIX compliant threads
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
+ Modified for Linux/Pthreads by Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de)
+
+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. */
+
+/* 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. */
+
+#include <objc/thr.h>
+#include "runtime.h"
+#include <pthread.h>
+
+/* Key structure for maintaining thread specific storage */
+static pthread_key_t _objc_thread_storage;
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
+int
+__objc_init_thread_system(void)
+{
+ /* Initialize the thread storage key */
+ return pthread_key_create(&_objc_thread_storage, NULL);
+}
+
+/* Close the threads subsystem. */
+int
+__objc_close_thread_system(void)
+{
+ return 0;
+}
+
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
+objc_thread_t
+__objc_thread_detach(void (*func)(void *arg), void *arg)
+{
+ objc_thread_t thread_id;
+ pthread_t new_thread_handle;
+
+ if ( !(pthread_create(&new_thread_handle, NULL, (void *)func, arg)) )
+ thread_id = *(objc_thread_t *)&new_thread_handle;
+ else
+ thread_id = NULL;
+
+ return thread_id;
+}
+
+/* Set the current thread's priority. */
+int
+__objc_thread_set_priority(int priority)
+{
+ /* Not implemented yet */
+ return -1;
+}
+
+/* Return the current thread's priority. */
+int
+__objc_thread_get_priority(void)
+{
+ /* Not implemented yet */
+ return -1;
+}
+
+/* Yield our process time to another thread. */
+void
+__objc_thread_yield(void)
+{
+ sched_yield();
+}
+
+/* Terminate the current thread. */
+int
+__objc_thread_exit(void)
+{
+ /* exit the thread */
+ pthread_exit(&__objc_thread_exit_status);
+
+ /* Failed if we reached here */
+ return -1;
+}
+
+/* Returns an integer value which uniquely describes a thread. */
+objc_thread_t
+__objc_thread_id(void)
+{
+ pthread_t self = pthread_self();
+
+ return *(objc_thread_t *)&self;
+}
+
+/* Sets the thread's local storage pointer. */
+int
+__objc_thread_set_data(void *value)
+{
+ return pthread_setspecific(_objc_thread_storage, value);
+}
+
+/* Returns the thread's local storage pointer. */
+void *
+__objc_thread_get_data(void)
+{
+ return pthread_getspecific(_objc_thread_storage);
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
+{
+ mutex->backend = objc_malloc(sizeof(pthread_mutex_t));
+
+ if (pthread_mutex_init((pthread_mutex_t *)mutex->backend, NULL))
+ {
+ objc_free(mutex->backend);
+ mutex->backend = NULL;
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Deallocate a mutex. */
+int
+__objc_mutex_deallocate(objc_mutex_t mutex)
+{
+ if (pthread_mutex_destroy((pthread_mutex_t *)mutex->backend))
+ return -1;
+
+ objc_free(mutex->backend);
+ mutex->backend = NULL;
+ return 0;
+}
+
+/* Grab a lock on a mutex. */
+int
+__objc_mutex_lock(objc_mutex_t mutex)
+{
+ return pthread_mutex_lock((pthread_mutex_t *)mutex->backend);
+}
+
+/* Try to grab a lock on a mutex. */
+int
+__objc_mutex_trylock(objc_mutex_t mutex)
+{
+ return pthread_mutex_trylock((pthread_mutex_t *)mutex->backend);
+}
+
+/* Unlock the mutex */
+int
+__objc_mutex_unlock(objc_mutex_t mutex)
+{
+ return pthread_mutex_unlock((pthread_mutex_t *)mutex->backend);
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ condition->backend = objc_malloc(sizeof(pthread_cond_t));
+
+ if (pthread_cond_init((pthread_cond_t *)condition->backend, NULL))
+ {
+ objc_free(condition->backend);
+ condition->backend = NULL;
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Deallocate a condition. */
+int
+__objc_condition_deallocate(objc_condition_t condition)
+{
+ if (pthread_cond_destroy((pthread_cond_t *)condition->backend))
+ return -1;
+
+ objc_free(condition->backend);
+ condition->backend = NULL;
+ return 0;
+}
+
+/* Wait on the condition */
+int
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ return pthread_cond_wait((pthread_cond_t *)condition->backend,
+ (pthread_mutex_t *)mutex->backend);
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ return pthread_cond_broadcast((pthread_cond_t *)condition->backend);
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__objc_condition_signal(objc_condition_t condition)
+{
+ return pthread_cond_signal((pthread_cond_t *)condition->backend);
+}
+
+/* End of File */
diff --git a/gnu/usr.bin/gcc/objc/thr-pthreads.c b/gnu/usr.bin/gcc/objc/thr-pthreads.c
new file mode 100644
index 00000000000..2efdd15bc54
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/thr-pthreads.c
@@ -0,0 +1,218 @@
+/* GNU Objective C Runtime Thread Implementation for PCThreads under GNU/Linux.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Scott Christley <scottc@net-community.com>
+ Condition functions added by: Mircea Oancea <mircea@first.elcom.pub.ro>
+
+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. */
+
+/* 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. */
+
+#include <pcthread.h>
+#include <objc/thr.h>
+#include "runtime.h"
+
+/* Key structure for maintaining thread specific storage */
+static pthread_key_t _objc_thread_storage;
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
+int
+__objc_init_thread_system(void)
+{
+ /* Initialize the thread storage key */
+ return pthread_key_create(&_objc_thread_storage, NULL);
+}
+
+/* Close the threads subsystem. */
+int
+__objc_close_thread_system(void)
+{
+ /* Destroy the thread storage key */
+ /* Not implemented yet */
+ /* return pthread_key_delete(&_objc_thread_storage); */
+ return 0;
+}
+
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
+objc_thread_t
+__objc_thread_detach(void (*func)(void *arg), void *arg)
+{
+ objc_thread_t thread_id;
+ pthread_t new_thread_handle;
+
+ if ( !(pthread_create(&new_thread_handle, NULL, (void *)func, arg)) )
+ thread_id = *(objc_thread_t *)&new_thread_handle;
+ else
+ thread_id = NULL;
+
+ return thread_id;
+}
+
+/* Set the current thread's priority. */
+int
+__objc_thread_set_priority(int priority)
+{
+ /* Not implemented yet */
+ return -1;
+}
+
+/* Return the current thread's priority. */
+int
+__objc_thread_get_priority(void)
+{
+ /* Not implemented yet */
+ return OBJC_THREAD_INTERACTIVE_PRIORITY;
+}
+
+/* Yield our process time to another thread. */
+void
+__objc_thread_yield(void)
+{
+ pthread_yield(NULL);
+}
+
+/* Terminate the current thread. */
+int
+__objc_thread_exit(void)
+{
+ /* exit the thread */
+ pthread_exit(&__objc_thread_exit_status);
+
+ /* Failed if we reached here */
+ return -1;
+}
+
+/* Returns an integer value which uniquely describes a thread. */
+objc_thread_t
+__objc_thread_id(void)
+{
+ pthread_t self = pthread_self();
+
+ return *(objc_thread_t *)&self;
+}
+
+/* Sets the thread's local storage pointer. */
+int
+__objc_thread_set_data(void *value)
+{
+ return pthread_setspecific(_objc_thread_storage, value);
+}
+
+/* Returns the thread's local storage pointer. */
+void *
+__objc_thread_get_data(void)
+{
+ void *value = NULL;
+
+ if ( !(pthread_getspecific(_objc_thread_storage, &value)) )
+ return value;
+
+ return NULL;
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
+{
+ if (pthread_mutex_init((pthread_mutex_t *)(&(mutex->backend)), NULL))
+ return -1;
+ else
+ return 0;
+}
+
+/* Deallocate a mutex. */
+int
+__objc_mutex_deallocate(objc_mutex_t mutex)
+{
+ if (pthread_mutex_destroy((pthread_mutex_t *)(&(mutex->backend))))
+ return -1;
+ else
+ return 0;
+}
+
+/* Grab a lock on a mutex. */
+int
+__objc_mutex_lock(objc_mutex_t mutex)
+{
+ return pthread_mutex_lock((pthread_mutex_t *)(&(mutex->backend)));
+}
+
+/* Try to grab a lock on a mutex. */
+int
+__objc_mutex_trylock(objc_mutex_t mutex)
+{
+ return pthread_mutex_trylock((pthread_mutex_t *)(&(mutex->backend)));
+}
+
+/* Unlock the mutex */
+int
+__objc_mutex_unlock(objc_mutex_t mutex)
+{
+ return pthread_mutex_unlock((pthread_mutex_t *)(&(mutex->backend)));
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ if (pthread_cond_init((pthread_cond_t *)(&(condition->backend)), NULL))
+ return -1;
+ else
+ return 0;
+}
+
+/* Deallocate a condition. */
+int
+__objc_condition_deallocate(objc_condition_t condition)
+{
+ return pthread_cond_destroy((pthread_cond_t *)(&(condition->backend)));
+}
+
+/* Wait on the condition */
+int
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ return pthread_cond_wait((pthread_cond_t *)(&(condition->backend)),
+ (pthread_mutex_t *)(&(mutex->backend)));
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ return pthread_cond_broadcast((pthread_cond_t *)(&(condition->backend)));
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__objc_condition_signal(objc_condition_t condition)
+{
+ return pthread_cond_signal((pthread_cond_t *)(&(condition->backend)));
+}
+
+/* End of File */
diff --git a/gnu/usr.bin/gcc/objc/thr-single.c b/gnu/usr.bin/gcc/objc/thr-single.c
new file mode 100644
index 00000000000..b196677c6b6
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/thr-single.c
@@ -0,0 +1,192 @@
+/* GNU Objective C Runtime Thread Implementation
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */
+
+/* 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. */
+
+#include <objc/thr.h>
+#include "runtime.h"
+
+/* Thread local storage for a single thread */
+static void *thread_local_storage = NULL;
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
+int
+__objc_init_thread_system(void)
+{
+ /* No thread support available */
+ return -1;
+}
+
+/* Close the threads subsystem. */
+int
+__objc_close_thread_system(void)
+{
+ /* No thread support available */
+ return -1;
+}
+
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
+objc_thread_t
+__objc_thread_detach(void (*func)(void *arg), void *arg)
+{
+ /* No thread support available */
+ return NULL;
+}
+
+/* Set the current thread's priority. */
+int
+__objc_thread_set_priority(int priority)
+{
+ /* No thread support available */
+ return -1;
+}
+
+/* Return the current thread's priority. */
+int
+__objc_thread_get_priority(void)
+{
+ return OBJC_THREAD_INTERACTIVE_PRIORITY;
+}
+
+/* Yield our process time to another thread. */
+void
+__objc_thread_yield(void)
+{
+ return;
+}
+
+/* Terminate the current thread. */
+int
+__objc_thread_exit(void)
+{
+ /* No thread support available */
+ /* Should we really exit the program */
+ /* exit(&__objc_thread_exit_status); */
+ return -1;
+}
+
+/* Returns an integer value which uniquely describes a thread. */
+objc_thread_t
+__objc_thread_id(void)
+{
+ /* No thread support, use 1. */
+ return (objc_thread_t)1;
+}
+
+/* Sets the thread's local storage pointer. */
+int
+__objc_thread_set_data(void *value)
+{
+ thread_local_storage = value;
+ return 0;
+}
+
+/* Returns the thread's local storage pointer. */
+void *
+__objc_thread_get_data(void)
+{
+ return thread_local_storage;
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
+{
+ return 0;
+}
+
+/* Deallocate a mutex. */
+int
+__objc_mutex_deallocate(objc_mutex_t mutex)
+{
+ return 0;
+}
+
+/* Grab a lock on a mutex. */
+int
+__objc_mutex_lock(objc_mutex_t mutex)
+{
+ /* There can only be one thread, so we always get the lock */
+ return 0;
+}
+
+/* Try to grab a lock on a mutex. */
+int
+__objc_mutex_trylock(objc_mutex_t mutex)
+{
+ /* There can only be one thread, so we always get the lock */
+ return 0;
+}
+
+/* Unlock the mutex */
+int
+__objc_mutex_unlock(objc_mutex_t mutex)
+{
+ return 0;
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ return 0;
+}
+
+/* Deallocate a condition. */
+int
+__objc_condition_deallocate(objc_condition_t condition)
+{
+ return 0;
+}
+
+/* Wait on the condition */
+int
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ return 0;
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ return 0;
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__objc_condition_signal(objc_condition_t condition)
+{
+ return 0;
+}
+
+/* End of File */
diff --git a/gnu/usr.bin/gcc/objc/thr-solaris.c b/gnu/usr.bin/gcc/objc/thr-solaris.c
new file mode 100644
index 00000000000..90351b43cf6
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/thr-solaris.c
@@ -0,0 +1,259 @@
+/* GNU Objective C Runtime Thread Interface
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
+ Conditions added by Mircea Oancea (mircea@first.elcom.pub.ro)
+
+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. */
+
+/* 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. */
+
+#include <objc/thr.h>
+#include "runtime.h"
+
+#include <thread.h>
+#include <synch.h>
+#include <errno.h>
+
+/* Key structure for maintaining thread specific storage */
+static thread_key_t __objc_thread_data_key;
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
+int
+__objc_init_thread_system(void)
+{
+ /* Initialize the thread storage key */
+ if (thr_keycreate(&__objc_thread_data_key, NULL) == 0)
+ return 0;
+ else
+ return -1;
+}
+
+/* Close the threads subsystem. */
+int
+__objc_close_thread_system(void)
+{
+ return 0;
+}
+
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
+objc_thread_t
+__objc_thread_detach(void (*func)(void *arg), void *arg)
+{
+ objc_thread_t thread_id;
+ thread_t new_thread_id = 0;
+
+ if (thr_create(NULL, 0, (void *)func, arg,
+ THR_DETACHED | THR_NEW_LWP,
+ &new_thread_id) == 0)
+ thread_id = *(objc_thread_t *)&new_thread_id;
+ else
+ thread_id = NULL;
+
+ return thread_id;
+}
+
+/* Set the current thread's priority. */
+int
+__objc_thread_set_priority(int priority)
+{
+ int sys_priority = 0;
+
+ switch (priority)
+ {
+ case OBJC_THREAD_INTERACTIVE_PRIORITY:
+ sys_priority = 300;
+ break;
+ default:
+ case OBJC_THREAD_BACKGROUND_PRIORITY:
+ sys_priority = 200;
+ break;
+ case OBJC_THREAD_LOW_PRIORITY:
+ sys_priority = 1000;
+ break;
+ }
+
+ /* Change priority */
+ if (thr_setprio(thr_self(), sys_priority) == 0)
+ return 0;
+ else
+ return -1;
+}
+
+/* Return the current thread's priority. */
+int
+__objc_thread_get_priority(void)
+{
+ int sys_priority;
+
+ if (thr_getprio(thr_self(), &sys_priority) == 0)
+ {
+ if (sys_priority >= 250)
+ return OBJC_THREAD_INTERACTIVE_PRIORITY;
+ else if (sys_priority >= 150)
+ return OBJC_THREAD_BACKGROUND_PRIORITY;
+ return OBJC_THREAD_LOW_PRIORITY;
+ }
+
+ /* Couldn't get priority. */
+ return -1;
+}
+
+/* Yield our process time to another thread. */
+void
+__objc_thread_yield(void)
+{
+ thr_yield();
+}
+
+/* Terminate the current thread. */
+int
+__objc_thread_exit(void)
+{
+ /* exit the thread */
+ thr_exit(&__objc_thread_exit_status);
+
+ /* Failed if we reached here */
+ return -1;
+}
+
+/* Returns an integer value which uniquely describes a thread. */
+objc_thread_t
+__objc_thread_id(void)
+{
+ return (objc_thread_t)thr_self();
+}
+
+/* Sets the thread's local storage pointer. */
+int
+__objc_thread_set_data(void *value)
+{
+ if (thr_setspecific(__objc_thread_data_key, value) == 0)
+ return 0;
+ else
+ return -1;
+}
+
+/* Returns the thread's local storage pointer. */
+void *
+__objc_thread_get_data(void)
+{
+ void *value = NULL;
+
+ if (thr_getspecific(__objc_thread_data_key, &value) == 0)
+ return value;
+
+ return NULL;
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
+{
+ if (mutex_init( (mutex_t *)(&(mutex->backend)), USYNC_THREAD, 0))
+ return -1;
+ else
+ return 0;
+}
+
+
+/* Deallocate a mutex. */
+int
+__objc_mutex_deallocate(objc_mutex_t mutex)
+{
+ mutex_destroy((mutex_t *)(&(mutex->backend)));
+ return 0;
+}
+
+/* Grab a lock on a mutex. */
+int
+__objc_mutex_lock(objc_mutex_t mutex)
+{
+ if (mutex_lock((mutex_t *)(&(mutex->backend))) != 0)
+ return -1;
+ else
+ return 0;
+}
+
+/* Try to grab a lock on a mutex. */
+int
+__objc_mutex_trylock(objc_mutex_t mutex)
+{
+ if (mutex_trylock((mutex_t *)(&(mutex->backend))) != 0)
+ return -1;
+ else
+ return 0;
+}
+
+/* Unlock the mutex */
+int
+__objc_mutex_unlock(objc_mutex_t mutex)
+{
+ if (mutex_unlock((mutex_t *)(&(mutex->backend))) != 0)
+ return -1;
+ else
+ return 0;
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ return cond_init((cond_t *)(&(condition->backend)), USYNC_THREAD, NULL);
+}
+
+/* Deallocate a condition. */
+int
+__objc_condition_deallocate(objc_condition_t condition)
+{
+ return cond_destroy((cond_t *)(&(condition->backend)));
+}
+
+/* Wait on the condition */
+int
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ return cond_wait((cond_t *)(&(condition->backend)),
+ (mutex_t *)(&(mutex->backend)));
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ return cond_broadcast((cond_t *)(&(condition->backend)));
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__objc_condition_signal(objc_condition_t condition)
+{
+ return cond_signal((cond_t *)(&(condition->backend)));
+}
+
+/* End of File */
diff --git a/gnu/usr.bin/gcc/objc/thr-win32.c b/gnu/usr.bin/gcc/objc/thr-win32.c
new file mode 100644
index 00000000000..8570ffd997e
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/thr-win32.c
@@ -0,0 +1,272 @@
+/* GNU Objective C Runtime Thread Interface - Win32 Implementation
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */
+
+/* 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. */
+
+#include <objc/thr.h>
+#include "runtime.h"
+
+#ifndef __OBJC__
+#define __OBJC__
+#endif
+#include <windows.h>
+
+/* Key structure for maintaining thread specific storage */
+static DWORD __objc_data_tls = (DWORD)-1;
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
+int
+__objc_init_thread_system(void)
+{
+ /* Initialize the thread storage key */
+ if ((__objc_data_tls = TlsAlloc()) != (DWORD)-1)
+ return 0;
+ else
+ return -1;
+}
+
+/* Close the threads subsystem. */
+int
+__objc_close_thread_system(void)
+{
+ if (__objc_data_tls != (DWORD)-1)
+ TlsFree(__objc_data_tls);
+ return 0;
+}
+
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
+objc_thread_t
+__objc_thread_detach(void (*func)(void *arg), void *arg)
+{
+ DWORD thread_id = 0;
+ HANDLE win32_handle;
+
+ if (!(win32_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func,
+ arg, 0, &thread_id)))
+ thread_id = 0;
+
+ return (objc_thread_t)thread_id;
+}
+
+/* Set the current thread's priority. */
+int
+__objc_thread_set_priority(int priority)
+{
+ int sys_priority = 0;
+
+ switch (priority)
+ {
+ case OBJC_THREAD_INTERACTIVE_PRIORITY:
+ sys_priority = THREAD_PRIORITY_NORMAL;
+ break;
+ default:
+ case OBJC_THREAD_BACKGROUND_PRIORITY:
+ sys_priority = THREAD_PRIORITY_BELOW_NORMAL;
+ break;
+ case OBJC_THREAD_LOW_PRIORITY:
+ sys_priority = THREAD_PRIORITY_LOWEST;
+ break;
+ }
+
+ /* Change priority */
+ if (SetThreadPriority(GetCurrentThread(), sys_priority))
+ return 0;
+ else
+ return -1;
+}
+
+/* Return the current thread's priority. */
+int
+__objc_thread_get_priority(void)
+{
+ int sys_priority;
+
+ sys_priority = GetThreadPriority(GetCurrentThread());
+
+ switch (sys_priority)
+ {
+ case THREAD_PRIORITY_HIGHEST:
+ case THREAD_PRIORITY_TIME_CRITICAL:
+ case THREAD_PRIORITY_ABOVE_NORMAL:
+ case THREAD_PRIORITY_NORMAL:
+ return OBJC_THREAD_INTERACTIVE_PRIORITY;
+
+ default:
+ case THREAD_PRIORITY_BELOW_NORMAL:
+ return OBJC_THREAD_BACKGROUND_PRIORITY;
+
+ case THREAD_PRIORITY_IDLE:
+ case THREAD_PRIORITY_LOWEST:
+ return OBJC_THREAD_LOW_PRIORITY;
+ }
+
+ /* Couldn't get priority. */
+ return -1;
+}
+
+/* Yield our process time to another thread. */
+void
+__objc_thread_yield(void)
+{
+ Sleep(0);
+}
+
+/* Terminate the current thread. */
+int
+__objc_thread_exit(void)
+{
+ /* exit the thread */
+ ExitThread(__objc_thread_exit_status);
+
+ /* Failed if we reached here */
+ return -1;
+}
+
+/* Returns an integer value which uniquely describes a thread. */
+objc_thread_t
+__objc_thread_id(void)
+{
+ return (objc_thread_t)GetCurrentThreadId();
+}
+
+/* Sets the thread's local storage pointer. */
+int
+__objc_thread_set_data(void *value)
+{
+ if (TlsSetValue(__objc_data_tls, value))
+ return 0;
+ else
+ return -1;
+}
+
+/* Returns the thread's local storage pointer. */
+void *
+__objc_thread_get_data(void)
+{
+ return TlsGetValue(__objc_data_tls); /* Return thread data. */
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
+{
+ if ((mutex->backend = (void *)CreateMutex(NULL, 0, NULL)) == NULL)
+ return -1;
+ else
+ return 0;
+}
+
+/* Deallocate a mutex. */
+int
+__objc_mutex_deallocate(objc_mutex_t mutex)
+{
+ CloseHandle((HANDLE)(mutex->backend));
+ return 0;
+}
+
+/* Grab a lock on a mutex. */
+int
+__objc_mutex_lock(objc_mutex_t mutex)
+{
+ int status;
+
+ status = WaitForSingleObject((HANDLE)(mutex->backend), INFINITE);
+ if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
+ return -1;
+ else
+ return 0;
+}
+
+/* Try to grab a lock on a mutex. */
+int
+__objc_mutex_trylock(objc_mutex_t mutex)
+{
+ int status;
+
+ status = WaitForSingleObject((HANDLE)(mutex->backend), 0);
+ if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
+ return -1;
+ else
+ return 0;
+}
+
+/* Unlock the mutex */
+int
+__objc_mutex_unlock(objc_mutex_t mutex)
+{
+ if (ReleaseMutex((HANDLE)(mutex->backend)) == 0)
+ return -1;
+ else
+ return 0;
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Deallocate a condition. */
+int
+__objc_condition_deallocate(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Wait on the condition */
+int
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__objc_condition_signal(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* End of File */
diff --git a/gnu/usr.bin/gcc/objc/thr.c b/gnu/usr.bin/gcc/objc/thr.c
new file mode 100644
index 00000000000..f1c957aaa15
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/thr.c
@@ -0,0 +1,534 @@
+/* GNU Objective C Runtime Thread Interface
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */
+
+/* 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. */
+
+#include <stdlib.h>
+#include "runtime.h"
+
+/* Global exit status. */
+int __objc_thread_exit_status = 0;
+
+/* Flag which lets us know if we ever became multi threaded */
+int __objc_is_multi_threaded = 0;
+
+/* The hook function called when the runtime becomes multi threaded */
+objc_thread_callback _objc_became_multi_threaded = NULL;
+
+/*
+ Use this to set the hook function that will be called when the
+ runtime initially becomes multi threaded.
+ The hook function is only called once, meaning only when the
+ 2nd thread is spawned, not for each and every thread.
+
+ It returns the previous hook function or NULL if there is none.
+
+ A program outside of the runtime could set this to some function so
+ it can be informed; for example, the GNUstep Base Library sets it
+ so it can implement the NSBecomingMultiThreaded notification.
+ */
+objc_thread_callback objc_set_thread_callback(objc_thread_callback func)
+{
+ objc_thread_callback temp = _objc_became_multi_threaded;
+ _objc_became_multi_threaded = func;
+ return temp;
+}
+
+/*
+ Private functions
+
+ These functions are utilized by the frontend, but they are not
+ considered part of the public interface.
+ */
+
+/*
+ First function called in a thread, starts everything else.
+
+ This function is passed to the backend by objc_thread_detach
+ as the starting function for a new thread.
+ */
+struct __objc_thread_start_state
+{
+ SEL selector;
+ id object;
+ id argument;
+};
+
+static volatile void
+__objc_thread_detach_function(struct __objc_thread_start_state *istate)
+{
+ /* Valid state? */
+ if (istate) {
+ id (*imp)(id,SEL,id);
+ SEL selector = istate->selector;
+ id object = istate->object;
+ id argument = istate->argument;
+
+ /* Don't need anymore so free it */
+ objc_free(istate);
+
+ /* Clear out the thread local storage */
+ objc_thread_set_data(NULL);
+
+ /* Check to see if we just became multi threaded */
+ if (!__objc_is_multi_threaded)
+ {
+ __objc_is_multi_threaded = 1;
+
+ /* Call the hook function */
+ if (_objc_became_multi_threaded != NULL)
+ (*_objc_became_multi_threaded)();
+ }
+
+ /* Call the method */
+ if ((imp = (id(*)(id, SEL, id))objc_msg_lookup(object, selector)))
+ (*imp)(object, selector, argument);
+ else
+ objc_error(object, OBJC_ERR_UNIMPLEMENTED,
+ "objc_thread_detach called with bad selector.\n");
+ }
+ else
+ objc_error(nil, OBJC_ERR_BAD_STATE,
+ "objc_thread_detach called with NULL state.\n");
+
+ /* Exit the thread */
+ objc_thread_exit();
+}
+
+/*
+ Frontend functions
+
+ These functions constitute the public interface to the Objective-C thread
+ and mutex functionality.
+ */
+
+/* Frontend thread functions */
+
+/*
+ Detach a new thread of execution and return its id. Returns NULL if fails.
+ Thread is started by sending message with selector to object. Message
+ takes a single argument.
+ */
+objc_thread_t
+objc_thread_detach(SEL selector, id object, id argument)
+{
+ struct __objc_thread_start_state *istate;
+ objc_thread_t thread_id = NULL;
+
+ /* Allocate the state structure */
+ if (!(istate = (struct __objc_thread_start_state *)
+ objc_malloc(sizeof(*istate))))
+ return NULL;
+
+ /* Initialize the state structure */
+ istate->selector = selector;
+ istate->object = object;
+ istate->argument = argument;
+
+ /* lock access */
+ objc_mutex_lock(__objc_runtime_mutex);
+
+ /* Call the backend to spawn the thread */
+ if ((thread_id = __objc_thread_detach((void *)__objc_thread_detach_function,
+ istate)) == NULL)
+ {
+ /* failed! */
+ objc_mutex_unlock(__objc_runtime_mutex);
+ objc_free(istate);
+ return NULL;
+ }
+
+ /* Increment our thread counter */
+ __objc_runtime_threads_alive++;
+ objc_mutex_unlock(__objc_runtime_mutex);
+
+ return thread_id;
+}
+
+/* Set the current thread's priority. */
+int
+objc_thread_set_priority(int priority)
+{
+ /* Call the backend */
+ return __objc_thread_set_priority(priority);
+}
+
+/* Return the current thread's priority. */
+int
+objc_thread_get_priority(void)
+{
+ /* Call the backend */
+ return __objc_thread_get_priority();
+}
+
+/*
+ Yield our process time to another thread. Any BUSY waiting that is done
+ by a thread should use this function to make sure that other threads can
+ make progress even on a lazy uniprocessor system.
+ */
+void
+objc_thread_yield(void)
+{
+ /* Call the backend */
+ __objc_thread_yield();
+}
+
+/*
+ Terminate the current tread. Doesn't return.
+ Actually, if it failed returns -1.
+ */
+int
+objc_thread_exit(void)
+{
+ /* Decrement our counter of the number of threads alive */
+ objc_mutex_lock(__objc_runtime_mutex);
+ __objc_runtime_threads_alive--;
+ objc_mutex_unlock(__objc_runtime_mutex);
+
+ /* Call the backend to terminate the thread */
+ return __objc_thread_exit();
+}
+
+/*
+ Returns an integer value which uniquely describes a thread. Must not be
+ NULL which is reserved as a marker for "no thread".
+ */
+objc_thread_t
+objc_thread_id(void)
+{
+ /* Call the backend */
+ return __objc_thread_id();
+}
+
+/*
+ Sets the thread's local storage pointer.
+ Returns 0 if successful or -1 if failed.
+ */
+int
+objc_thread_set_data(void *value)
+{
+ /* Call the backend */
+ return __objc_thread_set_data(value);
+}
+
+/*
+ Returns the thread's local storage pointer. Returns NULL on failure.
+ */
+void *
+objc_thread_get_data(void)
+{
+ /* Call the backend */
+ return __objc_thread_get_data();
+}
+
+/* Frontend mutex functions */
+
+/*
+ Allocate a mutex. Return the mutex pointer if successful or NULL if the
+ allocation failed for any reason.
+ */
+objc_mutex_t
+objc_mutex_allocate(void)
+{
+ objc_mutex_t mutex;
+
+ /* Allocate the mutex structure */
+ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex))))
+ return NULL;
+
+ /* Call backend to create the mutex */
+ if (__objc_mutex_allocate(mutex))
+ {
+ /* failed! */
+ objc_free(mutex);
+ return NULL;
+ }
+
+ /* Initialize mutex */
+ mutex->owner = NULL;
+ mutex->depth = 0;
+ return mutex;
+}
+
+/*
+ Deallocate a mutex. Note that this includes an implicit mutex_lock to
+ insure that no one else is using the lock. It is legal to deallocate
+ a lock if we have a lock on it, but illegal to deallocate a lock held
+ by anyone else.
+ Returns the number of locks on the thread. (1 for deallocate).
+ */
+int
+objc_mutex_deallocate(objc_mutex_t mutex)
+{
+ int depth;
+
+ /* Valid mutex? */
+ if (!mutex)
+ return -1;
+
+ /* Acquire lock on mutex */
+ depth = objc_mutex_lock(mutex);
+
+ /* Call backend to destroy mutex */
+ if (__objc_mutex_deallocate(mutex))
+ return -1;
+
+ /* Free the mutex structure */
+ objc_free(mutex);
+
+ /* Return last depth */
+ return depth;
+}
+
+/*
+ Grab a lock on a mutex. If this thread already has a lock on this mutex
+ then we increment the lock count. If another thread has a lock on the
+ mutex we block and wait for the thread to release the lock.
+ Returns the lock count on the mutex held by this thread.
+ */
+int
+objc_mutex_lock(objc_mutex_t mutex)
+{
+ objc_thread_t thread_id;
+ int status;
+
+ /* Valid mutex? */
+ if (!mutex)
+ return -1;
+
+ /* If we already own the lock then increment depth */
+ thread_id = objc_thread_id();
+ if (mutex->owner == thread_id)
+ return ++mutex->depth;
+
+ /* Call the backend to lock the mutex */
+ status = __objc_mutex_lock(mutex);
+
+ /* Failed? */
+ if (status)
+ return status;
+
+ /* Successfully locked the thread */
+ mutex->owner = thread_id;
+ return mutex->depth = 1;
+}
+
+/*
+ Try to grab a lock on a mutex. If this thread already has a lock on
+ this mutex then we increment the lock count and return it. If another
+ thread has a lock on the mutex returns -1.
+ */
+int
+objc_mutex_trylock(objc_mutex_t mutex)
+{
+ objc_thread_t thread_id;
+ int status;
+
+ /* Valid mutex? */
+ if (!mutex)
+ return -1;
+
+ /* If we already own the lock then increment depth */
+ thread_id = objc_thread_id();
+ if (mutex->owner == thread_id)
+ return ++mutex->depth;
+
+ /* Call the backend to try to lock the mutex */
+ status = __objc_mutex_trylock(mutex);
+
+ /* Failed? */
+ if (status)
+ return status;
+
+ /* Successfully locked the thread */
+ mutex->owner = thread_id;
+ return mutex->depth = 1;
+}
+
+/*
+ Unlocks the mutex by one level.
+ Decrements the lock count on this mutex by one.
+ If the lock count reaches zero, release the lock on the mutex.
+ Returns the lock count on the mutex.
+ It is an error to attempt to unlock a mutex which this thread
+ doesn't hold in which case return -1 and the mutex is unaffected.
+ */
+int
+objc_mutex_unlock(objc_mutex_t mutex)
+{
+ objc_thread_t thread_id;
+ int status;
+
+ /* Valid mutex? */
+ if (!mutex)
+ return -1;
+
+ /* If another thread owns the lock then abort */
+ thread_id = objc_thread_id();
+ if (mutex->owner != thread_id)
+ return -1;
+
+ /* Decrement depth and return */
+ if (mutex->depth > 1)
+ return --mutex->depth;
+
+ /* Depth down to zero so we are no longer the owner */
+ mutex->depth = 0;
+ mutex->owner = NULL;
+
+ /* Have the backend unlock the mutex */
+ status = __objc_mutex_unlock(mutex);
+
+ /* Failed? */
+ if (status)
+ return status;
+
+ return 0;
+}
+
+/* Frontend condition mutex functions */
+
+/*
+ Allocate a condition. Return the condition pointer if successful or NULL
+ if the allocation failed for any reason.
+ */
+objc_condition_t
+objc_condition_allocate(void)
+{
+ objc_condition_t condition;
+
+ /* Allocate the condition mutex structure */
+ if (!(condition =
+ (objc_condition_t)objc_malloc(sizeof(struct objc_condition))))
+ return NULL;
+
+ /* Call the backend to create the condition mutex */
+ if (__objc_condition_allocate(condition))
+ {
+ /* failed! */
+ objc_free(condition);
+ return NULL;
+ }
+
+ /* Success! */
+ return condition;
+}
+
+/*
+ Deallocate a condition. Note that this includes an implicit
+ condition_broadcast to insure that waiting threads have the opportunity
+ to wake. It is legal to dealloc a condition only if no other
+ thread is/will be using it. Here we do NOT check for other threads
+ waiting but just wake them up.
+ */
+int
+objc_condition_deallocate(objc_condition_t condition)
+{
+ /* Broadcast the condition */
+ if (objc_condition_broadcast(condition))
+ return -1;
+
+ /* Call the backend to destroy */
+ if (__objc_condition_deallocate(condition))
+ return -1;
+
+ /* Free the condition mutex structure */
+ objc_free(condition);
+
+ return 0;
+}
+
+/*
+ Wait on the condition unlocking the mutex until objc_condition_signal()
+ or objc_condition_broadcast() are called for the same condition. The
+ given mutex *must* have the depth set to 1 so that it can be unlocked
+ here, so that someone else can lock it and signal/broadcast the condition.
+ The mutex is used to lock access to the shared data that make up the
+ "condition" predicate.
+ */
+int
+objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ objc_thread_t thread_id;
+
+ /* Valid arguments? */
+ if (!mutex || !condition)
+ return -1;
+
+ /* Make sure we are owner of mutex */
+ thread_id = objc_thread_id();
+ if (mutex->owner != thread_id)
+ return -1;
+
+ /* Cannot be locked more than once */
+ if (mutex->depth > 1)
+ return -1;
+
+ /* Virtually unlock the mutex */
+ mutex->depth = 0;
+ mutex->owner = (objc_thread_t)NULL;
+
+ /* Call the backend to wait */
+ __objc_condition_wait(condition, mutex);
+
+ /* Make ourselves owner of the mutex */
+ mutex->owner = thread_id;
+ mutex->depth = 1;
+
+ return 0;
+}
+
+/*
+ Wake up all threads waiting on this condition. It is recommended that
+ the called would lock the same mutex as the threads in objc_condition_wait
+ before changing the "condition predicate" and make this call and unlock it
+ right away after this call.
+ */
+int
+objc_condition_broadcast(objc_condition_t condition)
+{
+ /* Valid condition mutex? */
+ if (!condition)
+ return -1;
+
+ return __objc_condition_broadcast(condition);
+}
+
+/*
+ Wake up one thread waiting on this condition. It is recommended that
+ the called would lock the same mutex as the threads in objc_condition_wait
+ before changing the "condition predicate" and make this call and unlock it
+ right away after this call.
+ */
+int
+objc_condition_signal(objc_condition_t condition)
+{
+ /* Valid condition mutex? */
+ if (!condition)
+ return -1;
+
+ return __objc_condition_signal(condition);
+}
+
+/* End of File */
diff --git a/gnu/usr.bin/gcc/objc/thr.h b/gnu/usr.bin/gcc/objc/thr.h
new file mode 100644
index 00000000000..f904733695a
--- /dev/null
+++ b/gnu/usr.bin/gcc/objc/thr.h
@@ -0,0 +1,143 @@
+/* Thread and mutex controls for Objective C.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Galen C. Hunt (gchunt@cs.rochester.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.
+
+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. */
+
+/* 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. */
+
+
+#ifndef __thread_INCLUDE_GNU
+#define __thread_INCLUDE_GNU
+
+#include "objc/objc.h"
+
+/*************************************************************************
+ * Universal static variables:
+ */
+extern int __objc_thread_exit_status; /* Global exit status. */
+
+/********
+ * Thread safe implementation types and functions.
+ */
+
+/* Thread priorities */
+#define OBJC_THREAD_INTERACTIVE_PRIORITY 2
+#define OBJC_THREAD_BACKGROUND_PRIORITY 1
+#define OBJC_THREAD_LOW_PRIORITY 0
+
+/* A thread */
+typedef void * objc_thread_t;
+
+/* This structure represents a single mutual exclusion lock. */
+struct objc_mutex
+{
+ volatile objc_thread_t owner; /* Id of thread that owns. */
+ volatile int depth; /* # of acquires. */
+ void * backend; /* Specific to backend */
+};
+typedef struct objc_mutex *objc_mutex_t;
+
+/* This structure represents a single condition mutex */
+struct objc_condition
+{
+ void * backend; /* Specific to backend */
+};
+typedef struct objc_condition *objc_condition_t;
+
+/* Frontend mutex functions */
+objc_mutex_t objc_mutex_allocate(void);
+int objc_mutex_deallocate(objc_mutex_t mutex);
+int objc_mutex_lock(objc_mutex_t mutex);
+int objc_mutex_unlock(objc_mutex_t mutex);
+int objc_mutex_trylock(objc_mutex_t mutex);
+
+/* Frontend condition mutex functions */
+objc_condition_t objc_condition_allocate(void);
+int objc_condition_deallocate(objc_condition_t condition);
+int objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex);
+int objc_condition_signal(objc_condition_t condition);
+int objc_condition_broadcast(objc_condition_t condition);
+
+/* Frontend thread functions */
+objc_thread_t objc_thread_detach(SEL selector, id object, id argument);
+void objc_thread_yield(void);
+int objc_thread_exit(void);
+int objc_thread_set_priority(int priority);
+int objc_thread_get_priority(void);
+void * objc_thread_get_data(void);
+int objc_thread_set_data(void *value);
+objc_thread_t objc_thread_id(void);
+
+/*
+ Use this to set the hook function that will be called when the
+ runtime initially becomes multi threaded.
+ The hook function is only called once, meaning only when the
+ 2nd thread is spawned, not for each and every thread.
+
+ It returns the previous hook function or NULL if there is none.
+
+ A program outside of the runtime could set this to some function so
+ it can be informed; for example, the GNUstep Base Library sets it
+ so it can implement the NSBecomingMultiThreaded notification.
+ */
+typedef void (*objc_thread_callback)();
+objc_thread_callback objc_set_thread_callback(objc_thread_callback func);
+
+/* Backend initialization functions */
+int __objc_init_thread_system(void);
+int __objc_fini_thread_system(void);
+
+/* Backend mutex functions */
+int __objc_mutex_allocate(objc_mutex_t mutex);
+int __objc_mutex_deallocate(objc_mutex_t mutex);
+int __objc_mutex_lock(objc_mutex_t mutex);
+int __objc_mutex_trylock(objc_mutex_t mutex);
+int __objc_mutex_unlock(objc_mutex_t mutex);
+
+/* Backend condition mutex functions */
+int __objc_condition_allocate(objc_condition_t condition);
+int __objc_condition_deallocate(objc_condition_t condition);
+int __objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex);
+int __objc_condition_broadcast(objc_condition_t condition);
+int __objc_condition_signal(objc_condition_t condition);
+
+/* Backend thread functions */
+objc_thread_t __objc_thread_detach(void (*func)(void *arg), void *arg);
+int __objc_thread_set_priority(int priority);
+int __objc_thread_get_priority(void);
+void __objc_thread_yield(void);
+int __objc_thread_exit(void);
+objc_thread_t __objc_thread_id(void);
+int __objc_thread_set_data(void *value);
+void * __objc_thread_get_data(void);
+
+#endif /* not __thread_INCLUDE_GNU */